moxt

Just another Blog site

Facebook製の画像ライブラリFrescoのコードを読んでいる

      2015/05/26

Facebookが新たに画像ライブラリFrescoを公開した。

DraweeView,DraweeController,DraweeHierarchyというクラスを利用したMVC的な構成を成しており、画像を効率よく読み込むようになっているらしい。(雑)

どのように画像を読み込んでいるのか気になったのでコードを読んでみた。

初期化から画像の読み込みまでの流れを追う

https://github.com/facebook/fresco/blob/master/drawee-backends/drawee-pipeline/src/main/java/com/facebook/drawee/backends/pipeline/Fresco.java

スタートはFrescoクラスから。

Getting startedではFresco.initialize(context)をApplicationのonCreateで呼び出している。

initializeを呼ぶとSimpleDraweeViewが初期化されてる。

SimpleDraweeViewはDraweeViewの拡張。

Getting startedではSimpleDraweeViewをXML上で宣言して、findById(…)でSimpleDraweeViewのインスタンスを取得してsetImageURIを呼び出している。

setImageURIは具体的にどのような処理をしてるのか。
下記の通り。

DraweeControllerを作ってアサインしてる。
シンプルだが、どうやって画像を読み込んで表示しているのか全く想像つかない。

でたらめにコードを読んでると、AbstractDraweeControllerのsubmitRequestというそれらしいメソッドがあった。

ここで深追いはしないが、mDataSource.subscribeで画像を取りに行って、dataSubscriberで非同期なイベント処理をしてる感じだろうか。

で、このsubmitRequestはAbstractDraweeControllerのonAttach内で呼び出されていた。
onAttachはDraweeControllerインタフェースの実装である。

では、コントローラーのonAttachは誰が呼び出しているのか。

突然だが、DraweeViewを見てみる。

DraweeViewはImageViewの拡張、上記のようにViewのライフサイクルイベントをフックにしてDraweeHolderクラスのonAttachを呼んでる。

と、いうわけでDraweeHolderを見る。

なるほど。
ControllerのonAttachを呼んでいることが確認できた。

  • DraweeHolderがViewライフサイクルとDraweeControllerとの仲介役になってる
  • ViewのonAttachに応じてAbstractDraweeControllerのonAttachが呼び出され、画像の読み込み処理を行うsubmitRequestメソッドが呼び出される

次はsubmitRequestメソッドの内容を深追いしてみたい。

> ここで深追いはしないが、mDataSource.subscribeで画像を取りに行って、dataSubscriberで非同期なイベント処理をしてる感じだろうか。

dataSubscriberはDataSubscriberインタフェースのインスタンス

mDataSourceはDataSourceインタフェースのインスタンス

DataSourceのsubscribeの実装はどこか。
AbstractDataSourceにあった。

既に結果がある、終了してる(通信?)、キャンセルされてる(通信?)の場合はSubscriberに通知してる。
何も無ければmSubscribersという不思議なQueueにSubscriberとExecutorをペアにして突っ込んでる。

結局、画像は誰が読み込んでいるのだ。
膨大なクラスに飲み込まれた。。

ImagePipelineとImageRequestが画像のダウンロードあたりを担当してそう。
Hierarchyはどこで登場するのだろう。。

路頭に迷った。

NetworkFetcher?

適当にコードを見る。

HttpUrlConnectionNetworkFetcher.java

なんかそれっぽい。
fetchメソッドでHttpUrlConnection使ってるし。

じゃあ、このNetworkFetcherって誰が使ってるんだろう。
NetworkFetchProducerがHttpUrlConnectionNetworkFetcherのfetchメソッドを呼んでいる。

 - Android

  • このエントリーをはてなブックマークに追加
  • follow us in feedly