LruCache(Least Recently Used Cache)はMaxSizeを超えたら最後に参照した順に追い出していく機能です
参照から外された対象は他の所から参照されなければgarbage collectionの対象になるのでOut of Memory対策として有効です。
もし、明示的に解放する必要のあるリソースの場合、
entryRemoved(boolean evicted, K key, V oldValue, V newValue)
をオーバーライドして、そこで解放してください。
キャッシュにキーに対応した値がなく、演算結果を返さなければいけない時、create(K key)
をオーバーライドすることで返す値をあらかじめ決めておくことが出来ます。
これを書いておくと常に正しい結果を返すことが出来て、呼び出し元のコードを簡略化が可能になります。
コンストラクタの概要 | |
---|---|
LruCache(int maxSize) |
メソッドの概要 | |
---|---|
final int | createCount() create(Object) で値を返した回数を返します |
final void | evictAll() エントリー毎に entryRemoved(boolean, K, V, V) を呼び出して、キャッシュをクリアにします。 |
final int | evictionCount() 追い出した回数を返します。 |
final V | get(K key) キャッシュ上の値かCreateで作られた値を返します。なければnullが返ります。 |
final int | hitCount() get(K) でキャッシュ上の値を使用した回数を返します。 |
final int | maxSize() sizeOf(K, V) をオーバーライドしなかったら、最大エントリー数を返す。 |
final int | missCount() get(K) でcreateで作られた値かnullを返した数。 |
final V | put(K key, V value) 指定された値と指定されたキーをこのキャッシュに関連付けます。 |
final int | putCount() put(K, V) が呼ばれた回数を返します。 |
final V | remove(K key) 指定されたキーのマッピングがあればキャッシュから削除します。 |
void | resize(int maxSize) キャッシュの上限を設定し直します。 |
final int | size() sizeOf(K, V) をオーバーライドしなかったら、キャッシュ上のエントリー数を返す。 |
final Map<K, V> | snapshot() 今現在のキャシュの状況をコピーして返します。 |
final String | toString() このオブジェクトが人間に読める簡潔な文字列を返します。 (maxSize hit missCount hitRateが分かる形) |
void | trimToSize(int maxSize) 合計のサイズがmaxSizeになるように調整します。 |
実際に実装してみます
例えばBitmapをStringをキーとしてキャッシュすると
import android.graphics.Bitmap; import android.support.v4.util.LruCache; import android.util.Log; import java.util.Map; import java.util.Set; public class LruBitmapCache extends LruCache<String, Bitmap> { private Bitmap mDefaultBitmap; public LruBitmapCache(int maxSize) { super(maxSize); } /** * {@link #get(Object)}で見つからなかった時に{@link #create(String)}で返す値をここで設定する * 設定しなかったらnullが返る * おすすめはNowLoading画像をここで設定しておいて画像準備出来たら{@link #put(Object, Object)}してキャッシュする * * @param defaultBitmap */ public void setDefaultBitmap(Bitmap defaultBitmap) { mDefaultBitmap = defaultBitmap; } /** * {@link #setDefaultBitmap(Bitmap)}で設定した値が返る * * @param key * @return */ @Override protected Bitmap create(String key) { return mDefaultBitmap; } @Override protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) { oldValue.recycle(); super.entryRemoved(evicted, key, null, newValue); } @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount(); } public void print() { Map<String, Bitmap> map = snapshot(); Set<Map.Entry<String, Bitmap>> entrySet = map.entrySet(); StringBuilder stringBuilder=new StringBuilder(); for (Map.Entry<String, Bitmap> mapEntry : entrySet) { stringBuilder.append(mapEntry.getKey()).append(" "); } Log.d("CachePrint", stringBuilder.toString()); } }
こんな感じで実装できます。