系列文章
Glide手写实现之资源封装
Glide手写实现之活动缓存
Glide手写实现之内存缓存
Glide手写实现之磁盘缓存
Glide手写实现之生命周期关联
Glide手写实现之网络图片加载实现
Glide手写实现之复用池
内存缓存
Glide中的内存缓存是二级缓存,当活动缓存中取不到资源的时候,再从内存缓存中取。内存缓存用的LRU算法缓存。其原理是当缓存已满再加入元素时最不常使用的元素会被移除。
LRU算法
LRU算法的原理比较简单,数据存储的数据结构为链表。当访问数据时,如缓存中有数据,则将该数据移动至链表的顶端;没有该数据则在顶端加入该数据,并移除链表中的低端的数据。
LRUCache
Android的v4兼容包中已经实现了LRUCache,底层使用的是LinkedHashMap。LinkedHashMap自身已经实现了顺序存储,默认情况下是按照元素的添加顺序存储,也可以启用按照访问顺序存储,即最近读取的数据放在最前面,最早读取的数据放在最后面,然后它还有一个判断是否删除最老数据的方法,默认是返回false,即不删除数据,我们使用LinkedHashMap实现LRU缓存的方法就是对LinkedHashMap实现简单的扩展,扩展方式有两种,一种是inheritance,一种是delegation,具体使用什么方式看个人喜好
对LRUCache封装成内存缓存
增加了删除元素时的回调,并且区分手动删除或者自动删除,只有自动删除的时候,才调用回调方法。
/**
* 内存缓存--LRU算法
*/
public class MemoryCache extends LruCache<String, Value> {
private boolean shoudonRemove;
// TODO 手动移除
public Value shoudonRemove(String key) {
shoudonRemove = true;
Value value = remove(key);
shoudonRemove = false; // !shoudonRemove == 被动的
return value;
}
// put get
private MemoryCacheCallback memoryCacheCallback;
public void setMemoryCacheCallback(MemoryCacheCallback memoryCacheCallback) {
this.memoryCacheCallback = memoryCacheCallback;
}
/**
* 传入元素最大值,给LruCache
* @param maxSize
*/
public MemoryCache(int maxSize) {
super(maxSize);
}
@Override
protected int sizeOf(@NonNull String key, @NonNull Value value) {
// return super.sizeOf(key, value);
Bitmap bitmap = value.getmBitmap(); // 8
// 最开始的时候
// int result = bitmap.getRowBytes() * bitmap.getHeight();
// API 12 3.0
// result = bitmap.getByteCount(); // 在bitmap内存复用上有区别 (所属的)
// API 19 4.4
// result = bitmap.getAllocationByteCount(); // 在bitmap内存复用上有区别 (整个的)
int sdkInt = Build.VERSION.SDK_INT;
if (sdkInt >= Build.VERSION_CODES.KITKAT) {
return bitmap.getAllocationByteCount();
}
return bitmap.getByteCount();
}
/**
* 1.重复的key
* 2.最少使用的元素会被移除
* @param evicted
* @param key
* @param oldValue
* @param newValue
*/
@Override
protected void entryRemoved(boolean evicted, @NonNull String key, @NonNull Value oldValue, @Nullable Value newValue) {
super.entryRemoved(evicted, key, oldValue, newValue);
if (memoryCacheCallback != null && !shoudonRemove) { // !shoudonRemove == 被动的
memoryCacheCallback.entryRemovedMemoryCache(key, oldValue);
}
}
}