文章目录
  1. 1. 1、LruCache是什么?
  2. 2. 2、如何使用LruCache?
  3. 3. 3、总结:

1、LruCache是什么?

最初我也不知道去缓存请求到的数据,直接都是通过http请求,根据得到的返回数据展示到界面上,网络不好时要等待好久请求才能成功,或者干脆就失败了,这样给用户的体验是很不好的。之后在学习中,了解到了Android SDK中有处理缓存的LruCache,这个LruCache是在android.util包下的,是API level 12引入的,对于API level 12之前的系统可以使用support library v4中的LruCache。

1.LruCache是一个泛型类。
2.LRU是Least Recently Used的缩写,即“最近最少使用”,说明LRU缓存算法的淘汰策略是把最近最少使用的数据移除,让出内存给最新读取的数据。
3.它采用的是内存缓存数据,它内部采用一个LinkedHashMap以强引用的方式存储外界的缓存对象。
4.它是线程安全的。
5.其中提供了put、get、remove方法来完成缓存的添加、获取和移除操作。
6.每次添加的缓存对象会置顶,当缓存满时,LruCache会移除较早使用的缓存对象,然后再添加新的缓存对象。

通常我们需要用到的缓存策略,简单的来说是将从网络请求得到的数据先缓存到内存中,等到下次再请求的时候,先从缓存中去获取,如果缓存中有,就将缓存数据取出;如果没有,则再从网络上请求,这是一种基本的缓存策略。

2、如何使用LruCache?

我将以ImageLoader 项目为例说明LruCache的使用方法。

由于support v4包中的LruCache可以用于API level 12之前的系统,和android.util包的LruCache的区别是在trimToSize中获取将要删除元素的方法不一样:

  • android.util.LruCache
1
Map.Entry<K, V> toEvict = map.eldest();
  • android.support.v4.util.LruCache
1
Map.Entry<K, V> toEvict = map.entrySet().iterator().next();

LinkedHashMap的eldest()方法已经被标注为@hide,所以考虑到兼容性的问题,建议使用android.support.v4.util.LruCache。

(1) 定义LruCache对象的引用,并且实例化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* 利用Runtime运行时来获取最大的内存大小
*/
public ImageLoader() {
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 8; //官方推荐1/8,可根据要缓存的图片大小进行调整
mCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
Log.d(TAG, "sizeOf: "+value.getByteCount());
return value.getByteCount();
//也可以return value.getRowBytes() * value.getHeight();
}
};
}

注意: 由源码可知在safeSizeOf 方法中有调用sizeOf ,默认返回1,这显然不合理,所以我们肯定是需要重写的,将value的大小作为每个item的size。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private int safeSizeOf(K key, V value) {
int result = sizeOf(key, value);
if (result < 0) {
throw new IllegalStateException("Negative size: " + key + "=" + value);
}
return result;
}
/**
* Returns the size of the entry for {@code key} and {@code value} in
* user-defined units. The default implementation returns 1 so that size
* is the number of entries and max size is the maximum number of entries.
*
* <p>An entry's size must not change while it is in the cache.
*/
protected int sizeOf(K key, V value) {
return 1;
}

(2) 添加缓存对象

在得到LruCache对象的实例后,可以通过put(String key, Bitmap value) 方法,将对象添加进去。

1
2
3
4
5
6
7
8
9
10
/**
* 将图片添加到缓存中,以url为key,以bitmap为value;
* @param url
* @param bitmap
*/
public void addBitmapToCache(String url, Bitmap bitmap) {
if (getBitmapFromCache(url) == null) {
mCache.put(url, bitmap);
}
}

(3) 获取缓存对象

通过get(String key) 方法,得到对于的缓存对象。

1
2
3
4
5
6
7
8
/**
* 从缓存中获取图片
* @param url
* @return
*/
public Bitmap getBitmapFromCache(String url) {
return !TextUtils.isEmpty(url) ? mCache.get(url) : null;
}

(4) 删除缓存对象

1
2
3
4
5
6
7
8
9
/**
* 从缓存中删除图片
* @param url
*/
public void removeBitmapFromCache(String url) {
if (!TextUtils.isEmpty(url)) {
mCache.remove(url);
}
}

关于android.util.LruCache的源码解析:http://www.jianshu.com/p/f32e5d435d6c

3、总结:

从使用上来看,LruCache并不复杂,map的操作很容易看懂,我们在项目中可以多使用这些缓存策略,会提升我们APP的用户体验,重点还有节省流量哦!

文章目录
  1. 1. 1、LruCache是什么?
  2. 2. 2、如何使用LruCache?
  3. 3. 3、总结: