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());
}
}こんな感じで実装できます。