这几天又重新把UIL的源码细读了,发现其中有太多值得我们借鉴学习的地方。
UIL官方文档网址:https://github.com/nostra13/Android-Universal-Image-Loader/wiki
UIL工作流程分析
UIL很好的帮助我们处理了图片加载、变换、缓存、显示,这其中涉及到的情况比较多,我就在这里主要分析一种工作流程:将一张图片(该图片是位于服务器上并且没有被加载过)显示在控件上。
首先我们简单的分析下,将一张图片显示在控件上,需要包括的几个动作:
- 通过http协议将服务器上的图片下载到本地
- 放入硬盘缓存
- 放入内存缓存
- 在UI线程上回调显示图片
其实UIL的主要工作流程就是这样的,只不过它封装和扩展的比较完善,而且它考虑到了各种极限条件。上一张UIL工作流程的介绍图
UIL是怎样判定控件被回收或被复用的
回收判定
一般需要在ImageView上显示图片会调用到displayImage(uri, new ImageViewAware(imageView), null, null, null)
,也就是说ImageView会被包装成ImageViewAeare,而ImageViewViewAware中保存的是WeakReference。判定是否被回收也就是通过viewRef.get() == null
。
|
|
复用判定
当ImageView被包装成ImageViewAware,ImageViewAware内部会有一个唯一标示Id。当每次调用displayImage时,会根据显示控件的大小产生出memoryCacheKey。ImageLoaderEngine中的Map
|
|
当UIL开始加载图片显示在控件时,一旦发现显示控件被回收和被复用,就会停止任务。
UIL如何处理加载显示同一个url
UIL会为每个url生成一个ReentrantLock,而后通过ReentrantLock实现多线程互斥操作,看代码
|
|
UIL对图片的处理
当UIL将服务器上的图片下载到本地后,需要将图片文件转换为Bitmap对象,在转换时就需要根据图片本身的大小和目标控件的大小进行缩放图片,有时候还需要对图片的角度进行变换。
|
|
计算图片缩放比例:主要是根据目标大小和源大小、控件ScaleType类型,计算scale用于BitmapOption
|
|
UIL默认的硬盘缓存
UIL默认用的硬盘缓存为LruDiskCache,其主要对DiskLruCache做了一层封装。
|
|
UIL默认的内存缓存
UIL默认用的内存缓存为LruMemoryCahce,其内部主要是用LinkedHashMap来实现LRU算法的。
|
|
总结
我这里只是简单的写了分析的几个重要的类和思路,其实源码阅读这个事情,还是需要自己一步一步去读懂才好,源码里有很多东西很难通过文字表达不来。