首先理解三级缓存:内存-本地-网络
- 加载图片首先判断内存是否有缓存,如果内存没有,判断本地是否有缓存,如果还是没有再从网络加载。
- 如果图片是从本地获取的,那么获取后保持到内存缓存,如果图片是从网络加载的,那么获取后保持到内存、本地缓存中
- 内存缓存推荐使用LruCache,本地缓存推荐使用DiskLruCache
目前流行的图片框架都是使用了三级缓存策略
LruCache
数据对象是LinkedHashMap,最近最少使用算法,使得最近访问的数据会在链表尾部,在容量溢出时,将链表头部的数据移除。
使用方法:
- 计算当前可用的内存大小;
- 分配LruCache缓存容量;
- 创建LruCache对象并传入最大缓存大小的参数、重写sizeOf()用于计算每个缓存对象的大小;
- 通过put()、get()和remove()实现数据的添加、获取和删除。
//初始化
//返回Java虚拟机将尝试使用的最大内存量
long maxMemory = Runtime.getRuntime().maxMemory() / 1024;
//这里的大小官方推荐是用当前app可用内存的八分之一
int cacheMaxSize = (int) (maxMemory/8);
mLruCache = new LruCache<String, Bitmap>(cacheMaxSize) {
//完成Bitmap对象大小计算
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight()/1024;
}
//在移除旧缓存的时候会调用,可以在这个方法做一些资源回收工作
@Override
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
super.entryRemoved(evicted, key, oldValue, newValue);
}
};
//获取缓存对象
mLruCache.get(key);
//添加缓存对象
mLruCache.put(key,value);
//移除缓存对象
mLruCache.remove(key);
DiskLruCache
通过将缓存对象写入文件系统从而实现缓存效果
创建DiskLruCache
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
- directory:磁盘缓存的存储路径。
- appVersion:当前应用的版本号,一般设为1。如果appVersion发生变化,会自动删除前一版本的数据
- valueCount:单个节点所对应的数据的个数,一般设为1。
- maxSize:缓存的总大小,超出这个设定值后DiskLruCache会清除一些缓存
利用Editor实现数据的添加
由于url中的字符可能会带文件名不支持的字符类型,所以取url的MD5值作为文件名
//返回url的MD5算法结果
String key = hashKeyForDisk(url);
//获取Editor对象
Editor editor = mDiskLruCache.edit(key);
OutputStream outputStream = editor.newOutputStream(0);
//写入数据
outputStream.wirte(data);
//提交写操作,若发生异常,则调用Editor.abort()进行回退。
editor.commit();
//将数据写入磁盘
mDiskLruCache.flush();
利用Snapshot实现数据获取。
//1.返回url的MD5算法结果
String key = hashKeyForDisk(url);
//2.获取Snapshot对象
Snapshot snapshot = mDiskLruCache.get(key);
InputStream inputStream = snapshot.getInputStream(0);
//4.读出数据
int data = inputStream.read();
推荐阅读:
网友评论