您的位置:首页 > 移动开发 > Android开发

android LruCache使用

2016-12-11 20:36 309 查看
  LruCache能够实现内存缓存,对于一些需要的资源,每次都去文件中获取效率比较低,毕竟内存读取快很多。LruCache内部使用的算法叫最少使用算法,当缓存满时,会淘汰掉最近使用最少的缓存对象。LruCache通过LinkedHashMap实现,通过它将需要的对象留在内存中。

  LruCache是线程安全的。

分析一下它的代码:

  构造函数:

public LruCache(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
}


  maxSize表示最大缓存值,可以看到内部创建了一个LinkedHashMap,该Map输入输出都是有顺序的。

  put方法:

/**
* Caches {@code value} for {@code key}. The value is moved to the head of
* the queue.
*
* @return the previous value mapped by {@code key}.
*/
public final V put(K key, V value) {
if (key == null || value == null) {
throw new NullPointerException("key == null || value == null");
}

V previous;
synchronized (this) {
putCount++;
size += safeSizeOf(key, value);
previous = map.put(key, value);
if (previous != null) {
size -= safeSizeOf(key, previous);
}
}

if (previous != null) {
entryRemoved(false, key, previous, value);
}

trimToSize(maxSize);
return previous;
}


  put方法将对象存放到缓存中,加了同步锁,保证线程安全,putCount表示添加到缓存中的数次数(该数不一定和缓存中有的对象个数相同)。size表示缓存大小。每次put后都要调用trimToSize()方法调整,判断缓存大小,如果缓存大小大于设定的最大值,不断删除缓存对象,直到缓存大小小于或等于设置的最大值。

  get方法:

public final V get(K key) {
if (key == null) {
throw new NullPointerException("key == null");
}

V mapValue;
synchronized (this) {
mapValue = map.get(key);
if (mapValue != null) {
hitCount++;
return mapValue;
}
missCount++;
}

/*
* Attempt to create a value. This may take a long time, and the map
* may be different when create() returns. If a conflicting value was
* added to the map while create() was working, we leave that value in
* the map and release the created value.
*/

V createdValue = create(key);
if (createdValue == null) {
return null;
}

synchronized (this) {
createCount++;
mapValue = map.put(key, createdValue);

if (mapValue != null) {
// There was a conflict so undo that last put
map.put(key, mapValue);
} else {
size += safeSizeOf(key, createdValue);
}
}

if (mapValue != null) {
entryRemoved(false, key, createdValue, mapValue);
return mapValue;
} else {
trimToSize(maxSize);
return createdValue;
}
}


  同样从缓存中获取数据的时候也加了同步锁,如果从缓存中对象存在,那么hitCount++,hitCount表示正确获取到对象的次数。不然missCount++,missCount表示丢失的次数,可能该对象由于缓存满了,从缓存中删去了,也可能该对象未加入过缓存。 那我们就要把当前值存入缓存。这里有一个create()方法,如果当前未得到数据,可以重写该方法,指定当前key值对应的对象。 之后会将该key和指定的值存入map中,如果map中之前存在该key值,就重新将之前的value值存入map中,而不是create()方法指定的值; 不然就是将key值和create()指定的值存入map中,size加上指定值的大小。最后调整缓存值。

  sizeof()方法:

需要重写该方法,该方法返回存入的对象的数据大小。

  这是几个比较重要的方法
a66b
,其它方法实现都是类似的,可以自己分析。

LruCache使用:

int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getHeight() * value.getRowBytes();
}
};


  一般初始化给定缓存大小为可用内存的1/8,重写sizeof()方法。

  获取当前key值对应的缓存对象:

mMemoryCache.get(key);


  将对象存放到缓存中

mMemoryCache.put(key, bitmap);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: