Android LruCache内存缓存实现详解
来源:互联网 发布:淘宝的购物车在哪里 编辑:程序博客网 时间:2024/06/05 10:32
Android开发中会遇到图片下载的操作,而图片下载为了不经常访问图片的网络请求,会做三级缓存:内存-文件-网络,同样这种缓存策略也适用其他文件的存储。首先,先拿图片URL去内存中找,如果没有就去文件中找,文件中没有找到,再去异步网络请求。下面,分析总结一下第一级缓存–内存缓存。
内存缓存会用到LruCache这个类,它是Android3.1所提供的一个缓存类,要想兼容Android3.1以下的版本,可以采用support-v4兼容包中提供的LruCache。
LruCache是一个泛型类,内部会实例化一个LinkedHashMap对象,它是实现Lru算法的关键。其中,Lru是最近最少使用算法,它的核心思想是当缓存满的时候,会优先淘汰那些最近最少使用的缓存对象。
new LinkedHashMap 《k,v》 (0,0.75f,true)
这句代码表示,0表示初始容量为零,0.75是加载因子,表示容量达到最大容量的75%时就会把内存增加一半。最后一个参数Boolean类型,它是至关重要的,true表示按访问顺序排序,false表示按插入顺序排序。
这里写了一个小程序专门研究这两个参数的不同之处。
当设置为true时,
public static final void main(String[] args) { LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>(0, 0.75f, true); map.put(0, 0); map.put(1, 1); map.put(2, 2); map.put(3, 3); map.put(4, 4); map.put(5, 5); map.put(6, 6); map.get(1); map.get(2); for (Map.Entry<Integer, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } }
输出的结果为:
0:0
3:3
4:4
5:5
6:6
1:1
2:2
而设置为false时,输出的顺序为:
0:0
1:1
2:2
3:3
4:4
5:5
6:6
有以上结果可以看出,这个设置为true时,如果对一个元素进行了操作(put,get),就会把那个元素放到集合的最后,设置为false时,无论怎么操作,集合元素的顺序都是按照插入的顺序来进行存储的。
由此可知,这个LinkedHashMap正是实现Lru算法的核心之处,当内容容量达到最大值时,只需要移除这个集合的前面的元素直到集合的容量足够存储数据时就可以了。
LruCache是线程安全的,提供了get()和put()方法来完成缓存的获取和添加操作。使用LruCache类时需要强应用,因为强应用不容易被GC回收。
其中put,get的源码如下
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; }
get()方法:
public final V get(K key) { if (key == null) { throw new NullPointerException("key == null"); } V mapValue; synchronized (this) { mapValue = map.get(key); if (mapValue != null) { hitCount++; return mapValue; } missCount++; } /* * Attempt to create a value. This may take a long time, and the map * may be different when create() returns. If a conflicting value was * added to the map while create() was working, we leave that value in * the map and release the created value. */ V createdValue = create(key); if (createdValue == null) { return null; } synchronized (this) { createCount++; mapValue = map.put(key, createdValue); if (mapValue != null) { // There was a conflict so undo that last put map.put(key, mapValue); } else { size += safeSizeOf(key, createdValue); } } if (mapValue != null) { entryRemoved(false, key, createdValue, mapValue); return mapValue; } else { trimToSize(maxSize); return createdValue; } }
使用LruCache类时:
int maxMemory = (int)Runtime.getRuntime().maxMemory()/1024;//app 可用最大内存数 int cacheSize = maxMemory/8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount()/1024; } @Override protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) { super.entryRemoved(evicted, key, oldValue, newValue); //如果需要的话,做一些资源回收操作 } };
其中,sizeof()方法,是用来计算缓存对象大小,单位要与总容量一致。需要重写sizeof方法,是因为原方法中返回值是不准确,不能准确判定value的值是什么类型,所以需要重写该方法。
除此之外,常用的还有remove方法。
- Android LruCache内存缓存实现详解
- Android LruCache内存缓存实现详解
- 内存缓存LruCache详解
- 内存缓存LruCache详解
- Android内存缓存LruCache
- Android 内存缓存 LruCache
- Android LruCache(内存缓存)
- Android LruCache(内存缓存)
- Android缓存LruCache详解
- 内存缓存LruCache实现原理
- 内存缓存LruCache实现原理
- 内存缓存LruCache实现原理
- 内存缓存LruCache实现原理
- 内存缓存LruCache实现原理
- Android 缓存(1)---内存缓存LruCache
- 使用lrucache实现图片内存缓存
- android 提供的内存缓存LruCache.java
- android LruCache内存缓存源码解析
- XML与HTML的设计区别
- java基础学习总结——流
- EasyAR从入门到精通开发系列教程(3)--移动端手指缩放
- 文章标题 Ultra-QuickSort
- eq相等 ne、neq不相等 EL表达式
- Android LruCache内存缓存实现详解
- 打开和关闭mysql服务的两种方法
- eigen与matlab对应函数列表
- "o_neww_ww_123"分割字符串split
- java基础学习总结——方法的重载(overload)
- Mars Stomatology gym 1007651 补牙(dp)
- String.replace()方法
- java基础学习总结——static关键字
- Java易混淆的概率:成员变量、类变量、实例变量、局部变量