Android图片三级缓存原理及LruCache、DiskLruCache的使用
首先附上我的几篇其它文章链接感兴趣的可以看看,如果文章有异议的地方欢迎指出,共同进步,顺便点赞谢谢!!!
Android framework 源码分析之Activity启动流程(android 8.0)
Android studio编写第一个NDK工程的过程详解(附Demo下载地址)
面试必备1:HashMap(JDK1.8)原理以及源码分析
面试必备2:JDK1.8LinkedHashMap实现原理及源码分析
Android事件分发机制原理及源码分析
View事件的滑动冲突以及解决方案
Handler机制一篇文章深入分析Handler、Message、MessageQueue、Looper流程和源码
三级缓存概述
缓存是一种通用的思想可以用在很多场景中,但在实际的开发中经常用于Bitmap的缓存,用于提高图片的加载效率、提升产品的用户体验和节省用户流量。目前常见的缓存策略是LruCache和DiskLruCachey用它们分别实现内存缓存和硬盘缓存。Lru是Least Recently Used的缩写即最近最少使用算法,这种算法思想是:当缓存容量快满时,会删除最近做少使用的缓存对象。在这里提醒大家一句三级缓存一般针对的是加载网络图片时常用的缓存策略。
附上我自定义的ImageLoader的代码地址去理解三级缓存原理:https://github.com/mayanhu/ImageLoader
三级缓存的流程
当我们要加载一张网络上的图片时一般流程:
- 按照一定的规则生成一个缓存Key,生成可以的算法自己可以定义保证唯一性就行,需要注意的是我们的key不要直接用图片的URL因为URL中的的特殊字符不方便处理
- 先去内存中通过key去读取内存中缓存的读取图片资源,如果内存中有则直接返回该对象
- 如果内存中没有则根据key从磁盘中读取,如果磁盘缓存有则:1. 返回该资源 2.将该资源重新放入内存缓存中 3. 将改资源从磁盘缓存中移除
- 如果磁盘缓存中也没有改图片资源,则发起网络请求,从网络获取图片资源
强引用 、弱引用 、软引用、虚引用的区别:
因为LruCache内部采用LinkedHashMap以强引用的形式缓存外界的对象,所以在讲LruCache前需要先了解Java对象(即堆内存中对象)引用的四个级别以及各自的特点,以便我们能更好的掌握内存缓存LruCache的实现原理。
- 强引用:是指我们直接引用的对象,如String s=new Stirng(“abc”),特点是:只要引用存在,垃圾回收器永远不会回收,如果无限制的使用new 强对象会抛出OOM异常。
- 软引用SoftReference:特点是:当一个对象只有软引用存在时,当系统内存不足时此对象会被GC回收。
- 弱引用WeakReference:当一个对象只有弱引用存在时,此对象随时会被GC回收。
- 虚引用PhantomReference:如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。
- 在此我只是简单描述了一下对象引用的特点,以便理解LruCache的实现原理,详细的用法和特点需要大家自行查阅资料,在这里不做过多描述。
内存缓存LruCache
首先简单说一下三级缓存为什么优先从内存中加载:
- 内存的加载速度时最快的,比从磁盘加载快的多
- 另一方面内存缓存的是Bitmap对象,可直接使用,而磁盘缓存的是文件需要我们先转换成对象才能使用
LruCache内部采用LinkedHashMap以强引用的形式缓存外界的对象,就是以键值对的形式缓存我们的Bitmap对象。LruCache是一个范型类,它是线程安全的因为它对数据的操作都加了锁。它的使用也很简单代码如下:
LruCache<String,Bitmap> mLruCache;
public void init(){
//当前进程的可用内存
int mxaMeory=(int)(Runtime.getRuntime().maxMemory()/1024);