AUIL 源码学习 重点问题
AUIL是个比较知名的图片加载库,源码结构比较清晰和简单,我在阅读学习中整理了以下内容。
MemoryCache
顾名思义,这个是在内存中缓存Bitmap相关的代码。
MemoryCache结合了策略模式和装饰器模式,初始化时可选择不同缓存策略。
一个Cache类内部持有一定量的Bitmap元素,并根据某种策略自动移除未使用的Bitmap。看结构我们应该从BaseMemoryCache开始看起。
BaseMemoryCache中持有了所有放入的元素的弱引用,而它的子类根据策略持有了部分缓存对象的强引用。
整个框架分多少个模块,每个模块的作用是什么
- ImageLoader 门面。
- ImageAware 对最终处理和展示图片操作的封装。
- MemoryCache bitmap在内存中的缓存。
- BitmapProcessor 图片处理器,处理原始图片。分为预处理和后处理,预处理的结果会存入缓存,而后处理每次展示都会执行。
- BitmapDisplayer 控制图片展示,可为其附加一定的展示效果。
- DiskCache bitmap在磁盘中的缓存
- ImageDecoder 将图片解码为Bitmap,并缩放到合适尺寸
如何仅通过interface就将框架的整个流程串联起来
如何进行内存管理的,LRU是种什么算法,有没有比LRU更好的?
AUIL的图片缓存有二级,一是所有缓存过的图片都会持有WeakReference,可能随时回收;二是部分图片会持有强引用,不会被回收。这里的部分图片的总共大小可以设置,达到阈值之后使用一定的算法淘汰一些图片。这里最常用的就是LRU。
LRU是淘汰缓存文件的算法,它每次淘汰最久未使用的文件。是一种最常用的页面置换算法。除了LRU之外,AUIL预置的算法还有FIFO(先入先出)、LargestLimitted(淘汰最大的文件)、LFU(淘汰使用频率最低的)。三者各有优劣。
如,LRU因为图片展示频率在时间上的不均匀性,可能将一些高频展示的图片淘汰掉,导致缓存命中率下降;LFU对于新图片频率统计无法比较好把控。
用到了多少个线程池,这些线程池之间的区别是什么,如果只用一个线程池可以么?
使用了三个线程池:
- taskExecutor
- taskExecutorForCachedImages
- taskDistributor
taskExecutor和taskExecutorForCachedImages都是用来执行图片处理和展示任务的,他们处理顺序都是个LIFO(后进先出)的队列,而taskDistributor是个普通的线程池,用于框架内其他任务。
taskExecutorForCachedImages是专门为缓存中读取的图片展示用的线程池,因为这类图片响应会很快,所以AUIL专门给他们准备了一个线程池。 综上,如果用一个线程池则最终效果会大打折扣。
最后修改于 2022-02-13