開発中のアプリに「ネット上からの画像の取得とキャッシュをする」処理があったので、不安定なオレオレ実装からGoogle謹製のVolleyに乗り換えてみました。
Volleyの導入やスタートアップはこちらなんかを参考にするといいと思います。
今回はVolleyを使う上での実用的なメモを備忘録代わりに書いておきます(@mhidakaさんに助けてもらいました)
1. 一度にRequestを投げすぎるな!
Volleyがレスポンスを返すおおまかな流れは
- Requestを生成
- RequestQueueに投げる
- ディスクキャッシュを探して見つかれば返す
- インターネットから拾ってきて返す
という感じです。RequestQueueに投げてからレスポンスを返すまでは別スレッドで動いてくれるので、UIスレッドを停止させることはありません。
ところで、このDispatcherがVolleyでは1つしかなくて並列化されていないので、短い時間に大量のRequestを投げてしまうとキューが溜まってしまってなかなか処理が終わりません。ですので「後で使うから予めプリキャッシュしておこう」という感じにVolleyを使うとパフォーマンス良くないです。必要なときに必要なだけ適切に投げてあげるといい感じに動きます。
2. ImageLoader+ImageCache
「ImageViewへネットからの画像読み込み」に特化した ImageLoader という仕組みがVolleyにあります。
ImageLoaderは画像に特化したRequest処理の実装で、内部にメモリキャッシュを持ちます。
こちらを見てもらえればわかりますが、ImageLoaderにはImageCacheというインタフェースのインスタンスを渡してあげることでメモリキャッシュが可能になってます。ImageLoaderを使った時の処理の流れは
- URLをImageLoaderに投げる
- URLをキーにメモリキャッシュを探索(高速)
- 見つからなければ勝手にRequestを生成してRequestQueueに投げる
- ディスクキャッシュを探して見つかれば返す(ここは単一スレッド)
- インターネットから拾ってきて返す
となっています。メモリキャッシュへのアクセスはそもそも早い上に並列化されているので画像を扱う場合は基本的にこのImageLoaderを使うのが鉄則だと思われます。
<追記>
メモリキャッシュの探索は並列化されてなかったので取り消しました
3.ImageLoader+NoCacheという選択肢
RequestQueueの生成時に渡すCacheは普通のサンプルコードではDiskBasedCacheだったりしますが、これを独自の空実装にしておけば、常にネットワークへアクセスさせることができます。この場合の処理の流れは
- URLをImageLoaderに投げる
- URLをキーにメモリキャッシュを探索(高速)
- 見つからなければ勝手にRequestを生成してRequestQueueに投げる
- ディスクキャッシュは必ず空
- インターネットから拾ってきて返す(4本並列で早い)
ネットワークからレスポンスを受け取るためのDispatcherはデフォルトで4つ用意されているのでレスポンスの投げ方やサイズ、回線状況によりますが、ディスクキャッシュよりもネットワークからのレスポンスのほうが早い場合もあります。なのでパフォーマンスを重視して一切キャッシュせずにVolleyを使うというのも十分にアリな選択です。
以上Volleyの私的メモでした。Volley素晴らしいのでみなさん使って流行らせましょう!