Android用の汎用ImageLoader

この記事では、画像を非同期にロードし、キャッシュして表示するために開発した(だけでなく)ツールについて説明します。 開発のこの段階では、インターネットまたはファイルシステムから画像をImageViewにアップロードする必要があるあらゆる場所で使用できます。 必要なのは、 イメージURL (ファイルシステムの場合は“ file://”で始まる)と、ダウンロードしたイメージを配置する必要があるImageView自体です。 ImageLoaderのユニバーサルの機能の詳細については、以下をお読みください。 すべてが1つのプロジェクトで始まり、そこに私は参加する機会がありました:ニュースのリストの表示を実装する必要があり、そしてもちろん、リストアイテムに写真を表示することについての質問が生じました。 写真はインターネットからダウンロードされたため、非同期の読み込み、表示、キャッシュを実装する必要がありました。 ネット上で簡単に検索した結果、 この問題に対する次のほぼ準備ができた解決策が見つかりました 。 実装されたLazyImageLoaderは、インターネットから非同期に画像をダウンロードし、ファイルシステムにキャッシュし、メモリに保存しました。 メモリ内の保存方法は、弱いリンクのない単純なHashMapでした。その結果、リストをスクロールする特定の段階でOutOfMemoryErrorが飛び出し始めました(そして、リストもたくさんありました)。 HashMapはWeakValueHashMapに置き換えられ、その後、メモリ制限のあるMapの独自の実装に置き換えられ、徐々にこのLazyImageLoaderに基づいて、独自のImageLoaderが独自のチップとトリックで成長し始めました。 リストだけでなくギャラリーでも写真を表示したり、簡単な「1回限りの」表示に使用できます。 このImageLoaderは、後に他の2つのプロジェクトで再利用され、その実行可能性が確認されました。 既存のコードを大幅にリファクタリングし、容認できる美しさをもたらしたので、 ソースコードをGitHubにアップロードしましたが、ここでツールがさらに最適化され、柔軟性とカスタマイズが向上します。 キャッシングはどうですか? キャッシングは次のように分かれています。 メモリキャッシュは、値に弱いリンクがあるHashMap <String、Bitmap>です。 どのように「弱」(ソフト、弱、ファントム)を決定するか:
public abstract class Cache<K, V> { protected final Map<K, Reference<V>> softMap = new HashMap<K, Reference<V>>(); public V get(K key) { if (softMap.containsKey(key)) { Reference<V> reference = softMap.get(key); return reference.get(); } else { return null; } } public void put(K key, V value) { softMap.put(key, createReference(value)); } public void clear() { softMap.clear(); } protected abstract Reference<V> createReference(V value); }
      
      



現在のバージョンでは、サイズを制御するビットマップキャッシュを使用しています。 これは、 ソフトマップからビットマップへの「強力な」リンクが保存された追加の「ハード」リストを導入することで実装されました。 キャッシュサイズが許容限度を超えると、「最も古い」オブジェクトが「ハードリスト」から削除されるため、強力なリンクが失われます。 弱いリンクはまだsoftMapに格納されていますが、ビットマップは既に完全にガベージコレクターの手に委ねられていますファイルシステムにキャッシュする場合 、ファイルはimageUrl.hashCode()と呼ばれ、同じ原理でキャッシュが検索されます。 ImageLoaderのメソッドは次のとおりです。
 void displayImage(String imageUrl, ImageView imageView, DisplayImageOptions options, ImageLoadingListener listener)
      
      



パラメータimageUrlimageViewは 、私が思うに、 問題引き起こすことはないと思いますDisplayImageOptionsクラスは、画像の読み込み、キャッシュ、表示のプロセスを設定するように設計されています。 これを使用して、以下を指定できます。 ImageLoadingListenerインターフェイスを使用すると、画像の読み込みプロセスを「聞く」ことができます。
 public interface ImageLoadingListener { void onLoadingStarted(); void onLoadingComplete(); }
      
      



ただし、現在の画像がメモリ内のキャッシュにある場合、 リスナーはイベントをスローしません。 UIストリームでイベントがスローされるため、 リスナーで静かな魂を使ってUIに触れることができるので、 ImageLoaderの使用例
 ImageLoader imageLoader = ImageLoader.getInstance(context); DisplayImageOptions options = new DisplayImageOptions.Builder() .showStubImage(R.drawable.stub_image) .cacheInMemory() .cacheOnDisc() .build(); imageLoader.displayImage(imageUrl, imageView, options, new ImageLoadingListener() { @Override public void onLoadingStarted() { spinner.show(); } @Override public void onLoadingComplete() { spinner.hide(); } });
      
      



ImageLoaderの動作のメカニズムについてはあまり説明しません。 私はいくつかのことだけを言います: もう一度、 GitHubソースへのリンクを提供しますが、このImageLoaderがお役に立てば幸いです。



UPD(2011年12月19日):ツールにいくつかの重要な変更が加えられました。それらの詳細とプロジェクト全体については、 こちらをご覧ください

UPD(2012年2月23日):多くの変更と改善が行われました(マルチスレッド、外部構成を含む)。 ただし、メインAPIは基本的に同じです。 これで、ツールがjarとして使用可能になりました。 バージョン管理が導入されました。

UPD(2012年3月11日):ライブラリの使用に関する詳細なガイド書きました。



All Articles