三级缓存
来源:互联网 发布:衣橱软件 编辑:程序博客网 时间:2024/04/28 02:47
三级缓存是:内存缓存,内存缓存,网络缓存。我们加载图片用得就是三级缓存。
他们读取的优先级:
1. 内存缓存 速度快, 优先读取
2. 本地缓存 速度其次, 内存没有,读本地
3. 网络缓存 速度最慢, 本地也没有,才访问网络
- 内存缓存:内存缓存指的是把图片缓存在内存里,需要再次用到的时候从内存读取。我们通常的做法是建一个集合,然后同过key,value,的形式存储。
这里我们要用软引用来做,因为不管android设备总内存是多大, 都只给每个app分配一定内存大小,这个内存通常只有十几M,到几十M。
所以一但缓存处理不当就很容易造成内存溢出。所以我们就要靠垃圾回收器来帮我们回收,从而减少内存溢出的可能。
平时new一个对象的时候,默认使用的是强引用,垃圾回收器是不会回收的,所以这里我们要使用软引用:
//声明一个软引用的集合 private HashMap<String, SoftReference<Bitmap>> mMemoryCache = new HashMap<String, SoftReference<Bitmap>>(); // 使用软引用将bitmap包装起来,然后存进集合 SoftReference<Bitmap> soft = new SoftReference<Bitmap>(bitmap); mMemoryCache.put(url, soft); //读取缓存的数据 SoftReference<Bitmap> softReference = mMemoryCache.get(url); if (softReference != null) { Bitmap bitmap = softReference.get(); return bitmap; }
用软引用把要存储的对象给包装起来,这样垃圾回收器会考虑回收,当然,出了软引用,还有弱引用和虚引用,垃圾回收器会更优先回收
弱引用,最优先回收虚引用。
但是,从 Android 2.3 (API 9)开始 垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。
Google建议使用LruCache。
重源码上可以看到,LruCache 和我们用软引用是差不多的,他只是给集合定了一个大小,当集合缓存的数据大小超过了定义的大小,
那么他就会把将最近最少使用的对象回收掉, 从而保证内存不会超出范围。
// 获取分配给app的内存大小 long maxMemory = Runtime.getRuntime().maxMemory(); //我们通常用app内存大小的8分之1 mMemoryCache = new LruCache<String, Bitmap>((int) (maxMemory / 8)) { // 返回每个缓存对象的大小 @Override protected int sizeOf(String key, Bitmap value) { // int byteCount = value.getByteCount(); int byteCount = value.getRowBytes() * value.getHeight();// 计算图片大小:每行字节数*高度 return byteCount; } };
这里是他删除缓存的条件:不停地执行循环,一旦集合大小超过了定义的大小,就把最前面的删除
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); } }
内存缓存就是这样了。
本地缓存:
把要缓存的文件存到sd卡里,同通常我们是把url同过MD5加密来当文件名来存储,因为有一些url里面包含特殊符号,创建文件会失败,
当我们要用到缓存的时候会用url加密成MD5看看sd卡里有没有这个文件,如果有就直接读取,再把文件存到内存里,如果没有,就再去从网络获取。网络缓存:
内存,和本地都没有缓存的时候,通过url去网络上获取到文件,然后再把文件缓存到本地和内存。
0 0