Android-Universal-Image-Loader的学习

2017-01-14 10:21:07来源:http://www.jianshu.com/p/7316ed92b5cb作者:RyanJerry人点击

Android开发中一定会遇到图片加载,图片缓存的问题。Universal-Image-Loader是我遇到过的比较不错的一个开源框架,是国外一个大牛写的,据说现在作者已经不维护了,下面就源码来学习一下,欢迎交流!

首先看源码目录结构





从目录中可见,Universal-Image-Loader(后面用UIL表示)提供了两种缓存方式,内存和磁盘。再来介绍一下UIL的缓存流程。

还是一张图。





①UI:请求数据,使用唯一的Key值索引Memory Cache中的Bitmap。

②内存缓存:缓存搜索,如果能找到Key值对应的Bitmap,则返回数据。否则执行第三步。

③硬盘存储:使用唯一Key值对应的文件名,检索SDCard上的文件。

④如果有对应文件,使用BitmapFactory.decode*方法,解码Bitmap并返回数据,同时将数据写入缓存。如果没有对应文件,执行第五步。

⑤下载图片:启动异步线程,从数据源下载数据(Web)。

⑥若下载成功,将数据同时写入硬盘和缓存,并将Bitmap显示在UI中。

上面片段摘自其他技术贴,应该都是浅显易懂。不过我来追加补充了解一下,加深认识。

首先是1的Key值,从代码中看Key值如何生成。

String memoryCacheKey = MemoryCacheUtils.generateKey(uri, targetSize);

可见,memoryCacheKey和图片url本身以及要显示的目标大小作为唯一key。就是说就算同一张图片,只要显示为不同尺寸,也不是用的

同一个bitmap。

另外3中的从代码查看是直接用文件名检索而不是先通过唯一key。

聊完基本业务流程,就来谈谈UIL都提供了哪些缓存算法。再来看一张图




从图片可以看出,UIL提供的内存缓存算法比较丰富,有8种,磁盘缓存则只有2种。下面稍微介绍一下各自算法的大致意思。

1、FIFOlimitedMemoryCache

先进先出的缓存策略,当超过设定值,先删除最先加入缓存的bitmap。

2、FuzzyKeyMemoryCache

这个是内部使用,用于比较bitmap是否存在,有则移除。

3、LimitedMemeryCache

使用强引用和弱引用结合的缓存策略,cacheSize以内的为强引用,cacheSize以外的为弱引用。

4、LargestLimitedMemeryCache

当超过缓存限定值,先删除最大的bitmap对象。

5、LimitedAgeMemoryCache

当 bitmap加入缓存中的时间超过我们设定的值,将其删除。

6、LRULMemoryCache

使用的LRU算法,当有需要时最近最少使用bitmap从缓存中删除。

7、LRULimitedMemoryCache

这个也是使用的LRU算法,和LruMemoryCache不同的是,他缓存加入了弱引用。cacheSize以内的为强引用,cacheSize以外的为弱引用。

8、WeakMemoryCache

这个算法只使用了弱引用来作为缓存策略。

接下来就是磁盘缓存

imitedAgeDiscCache

设定文件存活的最长时间,当超过这个值,就删除该文件。

UnlimitedDiscCache

这个缓存类没有任何的限制。

介绍完上面的缓存算法之后,大家是否都看到了,强引用、软引用、弱引用等概念。现在就这三个再介绍介绍。

1.强引用

以前我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。

2.软引用(SoftReference)

如果一个对象只具有软引用,那就类似于可有可物的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,JAVA虚拟机就会把这个软引用加入到与之关联的引用队列中。

3.弱引用(WeakReference)

如果一个对象只具有弱引用,那就类似于可有可物的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

其实UIL这个框架的代码中可以看到很多Java的一些编程思想,设计模式等。但出于时间考虑,先写这些,后面有时间继续补充。




最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台