Android Volleyを使って画像を取得&キャッシュ&表示

    どうも。伊藤です。

    Androidアプリを開発していると画像を扱うときにどうしても色々な壁にぶつかります。
    処理速度や操作性に拘らなければある程度スムーズに開発できますが、それだとどうしても納得できる使いやすさは実現できません。
    これらの課題を解決するためバージョンアップの度に新たなクラスやライブラリが追加されていますが、その中でVolleyというライブラリがあります。
    今回はこのVolleyライブラリを利用してサーバーから画像を取得&キャッシュ&画面に表示する方法について書きます。

    Volleyはネットワーク通信、データ取得、キャッシュや高速化などの課題を効率的に解決してくれるライブラリです。
    AndroidにはAsyncTask、Service、またそれらを拡張したAsyncTaskLoader、IntentServiceなど代表的なものやHandler、HttpClient、Threadなど非同期処理のための仕組みが豊富に存在していますが、非同期時のキャンセル処理や取得データのキャッシュ方法などサーバーから画像を取得&キャッシュ&表示するだけで様々な周辺技術と組み合わせる必要があります。

    Androidの標準APIは応用力が高く慣れれば簡単なのですが、慣れるまでの難しさ、エラーハンドリング、バージョン制御など色々な壁があります。
    ここらへんをVolleyを使って回避してみます。

    ライブラリはこちらからダウンロードいただくか、Gitなどバージョン管理ツールを利用している方であればリポジトリからソースを落としてください。
    その後にjarファイルを作成するか、ライブラリプロジェクトとして開発しているプロジェクトに紐付けてください。

    これで準備は完了なので続いて実装します。

    private RequestQueue rqQueue;
    private ImageLoader ilImage;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity);
      ・
      ・
      ・
      rqQueue = Volley.newRequestQueue(getApplicationContext());
      ilImage = new ImageLoader(rqQueue, new BitmapCache());
      ・
      ・
      ・
    }
    

    サーバーからの画像取得、キャッシュ、表示(取得中、取得後)は「ImageLoader.get(URL, listener)」を利用します。
    上記を利用するため、まずはRequestQueueのインスタンスを作成し、ImageLoaderのコンストラクタに設定します。
    これで最大5MB(変更可能)のディスクキャッシュが作られ、画像を取得する準備が整いました。
    RequestQueueとImageLoaderはコンストラクタやアクティビティであれば初期処理(onCreateなど)で定義して使いまわしましょう。
    ImageLoaderに設定しているBitmapCacheはImageCacheインターフェースを実装した画像キャッシュクラスです。

    次に画像を取得します。
    ListView、GridViewなどを利用している場合、getView()に以下2行を書きます。

    ImageListener listener = ImageLoader.getImageListener(ImageView, R.drawable.loading, android.R.drawable.nothing);
    ilImage.get(url, listener);
    

    画像を取得、キャッシュ、表示(取得中、取得後)してくれるImageLoader.getはパラメータに”URL”と”ImageListenerというインターフェースのインスタンス”を設定します。
    ImageListenerはImageLoader.getImageListener()で取得でき、第1引数に取得した画像を設定するImageView、第2引数にはローディング中のdrawable、第3引数には読み込みが失敗した際のdrawableを設定します。

    ListViewやGridViewのスクロール時の制御(スクロール時のキャンセル処理など)などUIに沿った制御はアプリ毎にもう少し必要になると思いますが、画像取得&キャッシュ&表示だけであればこれだけで実装は完了です。
    個人的にAsyncTaskLoaderやHttpClientなどを利用して独自に開発した画像取得&キャッシュ&表示クラスと比較すると、体感で3~4倍くらい早くなりました…少し悲しくもなりましたが素晴らしい!!
    ただ、ディスクキャッシュはメモリキャッシュより読み込みに時間を要し、長い時間キャッシュが不要なものには不向きです。用途によってメモリキャッシュとうまく使い分けていかないとですね。

    ではでは。