缓存机制涉及到技术核心点:内存缓存,磁盘(文件)缓存,LRU算法,基本数据结构。

图片缓存大致有如下2种:

内存缓存其实就是利用Map接口的对象在内存中进行缓存,可能有不同的存储机制。

磁盘缓存其实就是将文件写入磁盘。

缓存加载顺序如下图:

检测内存是否缓存->检查磁盘缓存->网络请求下载->根据配置策略选择是否内存缓存和写入磁盘。

一:内存缓存

1. 只使用的是强引用缓存 

  • LruMemoryCache(这个类就是这个开源框架默认的内存缓存类,缓存的是bitmap的强引用,下面我会从源码上面分析这个类)

 2.使用强引用和弱引用相结合的缓存有

 UsingFreqLimitedMemoryCache(如果缓存的图片总量超过限定值,先删除使用频率最小的bitmap)

  • LRULimitedMemoryCache(这个也是使用的lru算法,和LruMemoryCache不同的是,他缓存的是bitmap的弱引用)
  • FIFOLimitedMemoryCache(先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap)
  • LargestLimitedMemoryCache(当超过缓存限定值,先删除最大的bitmap对象)
  • LimitedAgeMemoryCache(当 bitmap加入缓存中的时间超过我们设定的值,将其删除)

 3.只使用弱引用缓存

 WeakMemoryCache(这个类缓存bitmap的总大小没有限制,唯一不足的地方就是不稳定,缓存的图片容易被回收掉)

下面单独介绍默认的LruMemoryCache:

内存缓存中用LinkedHashMap存储键值对,值就是我们需要显示的bitmap。我们通过键名来查询是否有这个bitmap.

其中内存缓存策略默认采用了LRU(Least Recently Used )算法,Imageloader图片加载框架模式使用LruMemoryCache策略。

LruMemoryCache是一种使用强引用来保存有数量限制的Bitmap的cache(在空间有限的情况,保留最近使用过的Bitmap)。

Bitmap用队列进行维护。

涉及到了强引用和弱引用概念:大家平时用的引用都是强引用,而弱引用是在系统内存不足时可能会回收引用的对象。

LRU:最近最少被使用。简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉。

简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉。

LinkedHashMap自身已经实现了顺序存储,默认情况下是按照元素的添加顺序存储,也可以启用按照访问顺序存储,即最近读取的数据放在最前面,最早读取的数据放在最后面,然后它还有一个判断是否删除最老数据的方法,默认是返回false,即不删除数据,我们使用LinkedHashMap实现LRU缓存的方法就是对LinkedHashMap实现简单的扩展。



二:磁盘缓存

  • FileCountLimitedDiscCache(可以设定缓存图片的个数,当超过设定值,删除掉最先加入到硬盘的文件)
  • LimitedAgeDiscCache(设定文件存活的最长时间,当超过这个值,就删除该文件)
  • TotalSizeLimitedDiscCache(设定缓存bitmap的最大值,当超过这个值,删除最先加入到硬盘的文件)
  • UnlimitedDiscCache(这个缓存类没有任何的限制)Imageloader默认磁盘缓存策略



磁盘缓存时候涉及到的技术点:


1、图片的命名会不会重。你没有办法知道用户下载的图片原始的图片名是怎么样的,因此很可能因为文件重名将有用的图片给覆盖掉了。String.hashCode()方法解决


2、当应用卡顿或网络延迟的时候,同一张图片反复被下载。 先检查Bitmap是否已经被缓。


3、处理图片写入磁盘可能遇到的延迟和同步问题。 synchronized同步代码块。