Android中的缓存策略

缓存策略

一般来说,缓存策略主要包含缓存的添加,获取和删除这三类操作。

1
删除缓存的原因:不管是内存缓存还是硬盘缓存,它们的缓存大小都是有限制的,当缓存容量满了之后,再想向其添加缓存,这个时候就需要删除一些旧的缓存并添加新的缓存。因此,如何定义缓存的新旧这就是一种策略,不同的策略对应着不同的缓存算法

LRU算法

LRU(Least Recently Used),近期最少使用算法,它的核心思想是当缓存满了,会优先淘汰那些近期最少使用的缓存对象。采用LRU算法的缓存有两种:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

## LruCache

### LruCache的介绍

核心思想:采用一个```LinkedHashMap```以强引用的方式存储外界的缓存对象,```LinkedHashMap```提供get和put方法来完成缓存的获取和添加操作,当缓存满时,```LruCache```会移除较早使用的缓存对象,然后再添加新的缓存对象。

1. 强引用、软引用和弱引用的区别:

- 强引用:直接的对象引用;
- 软引用:当一个对象只有软引用存在时,系统内存不足时此对象会被gc回收;
- 弱引用:当一个对象只有弱引用存在时,此对象会随时被gc回收。

2. ```LinkedHashMap```:是哈希表和链表的实现,它是线程不安全的,继承自```HashMap```,实现```Map<K, V>```接口。内部维护了一个双向链表,在插入、访问、修改数据时,会增加节点、或调整链表的节点顺序,双向链表结构可以保证迭代顺序是插入顺序。

```LinkedHashMap```的构造函数

```java
/**
* @param accessOrder the ordering mode
* true: access-order; false: insertion-order
*/
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder){
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}

1
2
3
4
5
6
7
8
9
10
11

另外```LruCache```是线程安全的,下面为其构造函数:

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

LruCache的使用

1
2
3
4
5
6
7
8
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxMemory / 8;
LruCache<String, Bitmap> memoryCache = new LruCache<String, Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
};
  1. 设置LruCache缓存的大小
  2. 重写sizeOf方法

LruCache的实现原理