2012年8月18日土曜日

LruCacheの使い方

TwitterのツイートをListViewに表示するという処理で、TwitterアイコンのキャッシュにLruCacheを使ってみたメモです。

馴れ初め(ダイジェスト)

TwitteアイコンのキャッシュにSoftReferenceを使っていたのですが、2.2 と 2.3 / 4.xで挙動が違って困っていたところ、以下のツイートに出会う。


ということで、Android Training「Caching Bitmaps」で使われていたLruCacheに辿り着いた次第です。
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

Twitter と 有益な情報をツイートしてくれる方々に感謝です。

コード

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
public final class ImageCache {
private static final int MEM_CACHE_SIZE = 1 * 1024 * 1024; // 1MB
private static LruCache<String, Bitmap> sLruCache;
static {
sLruCache = new LruCache<String, Bitmap>(MEM_CACHE_SIZE) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}
private ImageCache() {
}
public static void setImage(String key, Bitmap bitmap) {
if (getImage(key) == null) {
sLruCache.put(key, bitmap);
}
}
public static Bitmap getImage(String key) {
return sLruCache.get(key);
}
}
view raw ImageCache.java hosted with ❤ by GitHub

使い方

LruCacheはAPI Level 12からのクラスですが
http://developer.android.com/reference/android/util/LruCache.html
Support Libraryに入っているので
http://developer.android.com/reference/android/support/v4/util/LruCache.html
API Level 4から使えるようになっています。

使い方としては
・KeyとValueの型を指定してインスタンス化する
・LruCache#sizeOf()をオーバーライドしてBitmapのByte数を返してあげる
だけです。

Android TrainingのサンプルコードではBitmap#getByteCount()を使っていますがAPI Level 12からのメソッドなので上記の処理に書き換えています。
上記のコードではキャッシュサイズを1MB固定にしていますが、端末のDalvikVMヒープサイズから動的に決めたい場合は、Android TrainingのサンプルコードのようにすればOKです。

あとは、Twitterアイコン画像URLをKeyにBitmapをキャッシュしておいて、画像使用時にImageCache.getImage(Twitterアイコン画像URL)がnullだったら再取得というような処理にしておけばよいかと思います。

まとめ

2.3以降GCがモア アグレッシブになっているので、SoftReferenceを使用した場合、ListViewの行が画面から消えるとすぐに画像キャッシュがクリアされてしまう。
従って、今後はLruCacheを使いましょう。
といったところでしょうか。

LruCacheを利用することで、SoftReferenceを使用した場合の2.2 と 2.3以上でキャッシュの挙動が違うという問題が解決できました。
公式ドキュメントはちゃんとチェックしておかないとダメですね。。

因に僕は、常にこの構成でデバッグしています。
書いたコードに対してすぐにバージョン間の差異が確認できるので良いかなと思っています。
今のところ誰からも賛同を得られていませんが...

Fragmentationと共に生きる方法
http://neta-abc.blogspot.jp/2012/08/fragmentation.html


0 件のコメント:

コメントを投稿