今天讲解下图片缓存框架的解析与设计,在学习面向对象的任何框架之前,你要做的一件事情就是熟悉设计模式,废话不多说,直接进入主题,。
1.首先看一幅图,这幅图很清晰的告诉你,缓存框架要做哪些事情:
2 .下面这张图主要是为了反映这些模块是如何联系在一起的 (该图是缓存中都没有对应图片的时序图形)。
3 .下面是各个模块的实现细节
一、缓存模块设计
(1)运用模式 模板方法模式+装饰模式+享元模式(模式定义可参考其他资料)。
(2)整体类图
(3).关键实现部分详解
缓存框架上大体有两类实现
1.单纯弱引用:
WeakMemoryCache只实现抽象类中createReference()方法创建缓存对象,保存在非强引用的softMap享元池中,这种方式只要垃圾回收机制扫描到即被回收。
2.弱引用+强引用:(这种方式优势,即使是强引用享元池中的元素被移除,弱引用中的对象仍然可能被使用)
这种方式有三个享元池,三个池中存的Bitmap都是同一个对象,因此不用担心有浪费内存的行为,这里来分别讲下这三种池的作用:
BaseMemoryCache类中的非强引用softMap: 在强引用remove对象的时候,该池中内容可以无需被remove,由垃圾回收机制来处理。
LimitedMemoryCache类中的强引用hardCache享元池: 强引用享元池保证该对象不被垃圾回收机制回收,达到用户可以控制的目的。
以及具体实现类的享元池(FIFOLimitedMemoryCache、、): 用于实现各种策略的集合。
LRULimitedMemoryCache: 采用LinkedHashMap来实现最近最久未使用策略。
LinkedHashMap特点: LinkedHashMap重写了父类HashMap的get方法,实际在调用父类getEntry()方法取得查找的元素后,再判断当排序模式accessOrder为true时,记录访问顺序,将最新访问的元素添加到双向链表的表头,这样我们做移除操作时,移除遍历到的第一个元素即可,从而达到最近最久最使用的出列,并且将父类LimitedMemoryCache中的hardCache对应的对象移除。
LargestLimitedMemoryCache: 采用HashMap集合,当map中的大小超过规定大大小,即移除集合中最大的一个元素。HashMap中的value存放该图片的大小,key存放Bitmap对象,当hardCache大小大于规定大小的时候,遍历HashMap将value最大的移除。并且将父类LimitedMemoryCache中的hardCache对应的对象移除。
FIFOLimitedMemoryCache: 采用LinkedList集合List中的大小超过规定的大小,利用LinkedList自带的remove(0)方法来移除集合中的第一个元素。
UsingFreqLimitedMemoryCache: 采用HashMap集合当map中的大小超过规定带下,即移除集合中使用频率最小的一个元素,HashMap中的value存放该图片使用次数,key存放Bitmap对象。
注意:FuzzyKeyMemoryCache实现了接口所有方法,对传过来的缓存具体对象进行装饰,在对象被put的时候,增加一些其他移除规则。
比如图片的下载地址相同,但是需要的尺寸不同(保存缓存KEY的时候是要带上图片目标尺寸的),这个时候如果有新的图片存入缓存池就需要区分缓存对象中尺寸是否是用户当前想要的尺寸,不是则需要移除之前的BitMap对象。
二、显示包装模块
模式:类似中介者模式,将要处理的图片与ImageView传给中介者display,由中介者对图片进行处理后将图片与ImageView关联起来,对于外面来说无需关注其实如何关联在一起的。
图片在显示之前进行一些处理,比如圆角,淡入淡出、毛玻璃包装,用户可以自定义包装类。
三、图片获取模块
图片可以从其他应用中(相册)、手机中SD卡中、资源文件drawable、网络上(http、https)、assets等地方获取.
其他应用中获取(相册):ContentResolver
手机中获取:FileInputStream
assets: context.getAssets().open(filePath);
资源文件drawable:context.getResources().openRawResource(drawableId);
网络上(http、https):HttpURLConnection、httpClient
四、配置模块设计
初始配置项繁多,config对象构造复杂,因此整体采用建造者模式。
五、客户端监听模块
采用模式 观察者模式。由监听者由调用方传过来,当以下事件发发生时,即回调客户端。
1.开始下载LoadingStart
2.下载失败LoadingFailed
3.下载完成onLoadingComplete
4.下载取消onLoadingCancelled
六、其他优化措施:
在LISTVIEW,GrildView滚动过程中停止加载:
继承 OnScrollListener类,重写onScrollStateChanged方法,
OnScrollListener.SCROLL_STATE_IDLE时继续图片加载。
OnScrollListener.SCROLL_STATE_TOUCH_SCROLL,OnScrollListener.SCROLL_STATE_FLING时暂停图片加载。