android 缓存机制之 LruCache
来源:互联网 发布:普通发票软件下载 编辑:程序博客网 时间:2024/05/22 20:23
LruCache将数据缓存在内存中,虽然app的内存有限但是缓存一些必要的小一些的资源还是很有必要的,新建如下cache。
LruCache<String, Bitmap> mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getRowBytes() * bitmap.getHeight() / 1024; } };
需要定义
1缓存资源的个数cacheSize
2要怎么计算缓存资源的大小,sizeOf
使用也很简单,跟HashMap似得。
mMemoryCache.put(key, bitmap);mMemoryCache.get(key);使用put放入缓存,使用get获取缓存。
看一下源码:
1)构造函数
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最大缓存空间,单位和重写的SizeOf中使用的一致就可以了,比如都用byte。
新建了一个LinkedHashMap,这里有三个参数,
第一个HashMap初始大小,
第二个防hash冲突因子,简单说就是在HaspMap中的table数组最多只能利用3/4的空间,因为这个数组的index是利用hash值来计算的,为了减少冲突,只使用其中3/4的空间,超过之后,直接将数组容量翻倍。(这个参数并不影响理解LruCache)
第三个表示是否按照使用的先后顺序排序。(这里会影响,长时间不用的对象就会排到后面,当空间不够的时候,就要释放它了,因此这里传入true)
2)put
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; }
简答来说就是将对象存进LinkedHashMap, safeSizeOf这里会回调重写的SizeOf方法来获取当期对象的大小,size增加, 如果当前键值已经存在就被替换掉了,size减小。
trimToSize这里会根据size和maxSize大小的比较,来看是否超出最大缓存范围,超出就移除最早用过的那个缓存,直到小于maxsize。代码如下
public void trimToSize(int maxSize) { while (true) { K key; V value; synchronized (this) { if (size < 0 || (map.isEmpty() && size != 0)) { throw new IllegalStateException(getClass().getName() + ".sizeOf() is reporting inconsistent results!"); } if (size <= maxSize || map.isEmpty()) { break; } Map.Entry<K, V> toEvict = map.entrySet().iterator().next(); key = toEvict.getKey(); value = toEvict.getValue(); map.remove(key); size -= safeSizeOf(key, value); evictionCount++; } entryRemoved(true, key, value, null); } }
这样就实现了利用linkedHashMap缓存数据。
LinkedHashMap是如何控制移除对象优先级,代码如下在LinkedHas和Map中
void recordAccess(HashMap<K,V> m) { LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m; if (lm.accessOrder) { lm.modCount++; remove(); addBefore(lm.header); } }
每一次使用get()的时候,就会将当前对象移动到链表的头部(heaser)前面,因为LinkedHashMap的数据结构是个环形的双向链表,因此,在header后面的第一个就是最早用过的那个对象,也就是最不常用,在最后空间不足时,从heder后面第一个依次向后取,然后移除释放空间就可以了。
阅读全文
0 0
- android 缓存机制之 LruCache
- Android 缓存机制 LRUCache
- Android缓存机制Lrucache内存缓存和DiskLruCache磁盘缓存
- Android缓存机制:LruCache+AsyncTask缓存和显示网络图片
- android本地图片加载器,LruCache缓存机制
- Android LruCache 缓存图片
- android:LruCache缓存小结
- Android缓存-LruCache分析
- Android内存缓存LruCache
- android 图片缓存LruCache
- Android缓存框架 LruCache
- Android缓存LruCache详解
- Android 内存缓存 LruCache
- android 缓存技术lrucache
- Android LruCache(内存缓存)
- Android LruCache(内存缓存)
- Android源码解析之(七)-->LruCache缓存类
- 《android framework常用api源码分析》之LruCache内存缓存
- Leetcode 189 Rotate Array
- 先说IEnumerable,我们每天用的foreach你真的懂它吗?
- java.util.ResourceBundle使用详解
- GPS 经度纬度 坐标转换的以色列横轴墨卡托投影(ITM)
- 生成requirement.txt
- android 缓存机制之 LruCache
- 欢迎使用CSDN-markdown编辑器
- 内存缓存图片及原理
- AD转换 XPT2046
- Mybatis 遇到特殊字符处理
- SpringCloud系列(2)---Netfilx-Eureka
- poj1611----并查集的简单应用
- 安装python+setuptools+pip+nltk
- Less函数说明