- [ ] Android通用功能封装0——开篇
- [x] Android通用功能封装1——通用工具类封装
- [ ] Android 通用功能封装2——图片加载
- [ ] Android 通用功能封装3——文件选择
- [ ] Android 通用功能封装4——文件下载
- [ ] Android 通用功能封装5——网络库封装
- [ ] Android 通用功能封装6——数据库封装
- [ ] Android 通用功能封装7——广播管理
为什么要封装
现有的图片加载框架已经很好了,如Fresco、Glide等都有十分丰富的功能,但是会存在一个问题,如果没有在这个基础上进行封装,而是直接代码中使用的话,那么万一哪天我想把网络加载库从Fresco换成Glide的话,那么要替换的东西就很多,工作量就很大,所以封装时为了 控制反转,具体使用什么图片加载框架由使用者决定,不管用哪个加载库,对使用者而言,调用的API都是一样的,这就方便了 项目的移植,方便了功能的扩展,而且由于代码高内聚,低耦合,最终出问题的概率也会大大降低,这就是二次封装的意义。
封装方法
具体的封装策略就是提取各个加载框架的共性,同时支持某些加载框架的特性,共性是基础,指的是图片加载框架都具有的通用功能,特性值的是 只有某些加载框架才支持的特殊配制,这两个在封装的时候都需要考虑到,看下面这个类 ILoadStrategy
。
图片加载常用功能
常用功能对应的接口 ILoadStrategy
的具体实现如下:
1 | /** |
上面基本包含了每个图片加载框架都会有的常用功能,包括:
图片加载,通过
loadImage
实现;缓存清除,通过
clearCache
实现;清除指定图片缓存,通过
clearCacheKey
实现;判断图片是否缓存,通过
isCache
实现;获取缓存文件,通过
getLocalCache
实现;获取缓存的Bitmap,通过
getLocalCacheBitmap
实现;获取缓存配置的大小,通过
getCacheSize
实现;图片下载,通过
downloadOnly
实现;
然后就是定义了一个接口 ExtendedOptions
,它就是用来保留不通请求框架所独有的配置信息的,如果加载图片时,需要使用Glide特有的一些加载配置参数,就可将 Glide的请求配置对象RequestOptions
作为object参数传递到ExtendedOptions
的onOptionsInit(Object object)
,然后在这个方法的实现中将具体的特殊加载配置设置进去。
LoadConfg
为通用配置参数类,可以将通用的加载配置写到这个LoadConfig
中,然后各个框架分别取实现这个类,作为配置参数,这个类最好采用 建造者模式 来编写。
当然,上面只是定义了接口,具体的实现需要不通的图片加载框架具体实现,下面给出几个主流加载框架的 ILoadStrategy
实现。
Glide对应实现
Glide对应的ILoadStrategy
实现:GlideLoadStrategy
1 | public class GlideLoadStrategy implements ILoadStrategy { |
Fresco对应实现
Fresco 对应的ILoadStrategy
实现 FrescoLoadStrategy
:
1 | public class FrescoLoadStrategy extends BaseFrescoLoadStrategy implements ILoadStrategy { |
其中 BaseFrescoLoadStrategy 实现如下:
1 | public class BaseFrescoLoadStrategy { |
Picasso对应实现
Picasso 对应的 ILoadStrategy
实现PicassoLoadStrategy
:
1 | public class PicassoLoadStrategy implements ILoadStrategy { |
图片加载类
在不同图片加载对 ILoadStrategy的具体实现了之后,需要一个类来决定使用那个加载策略来进行图片的加载操作,这就是接下来这个ImageLoader
的作用了,通过在构造这个 ImageLoader 实例时为其传递一个 ILoadStrategy 的具体实现类,或者通过调用setLoadStrategy方法来设置具体的 ILoadStrategy,简单的说,这个类知识 一个代理,具体的加载实现都是通过 其成员变量 ILoadStrategy 来决定的。类的具体实现如下:
1 | public class ImageLoader implements ILoadStrategy{ |
到这,图片加载基本功能封装就完成了,调用者如果需要使用不通的图片加载框架,只需要在构造 ImageLoader 实例时传入不同的 ILoadStrategy 实现即可,但大多数情况下,一个App通常只需要使用一种 图片加载框架,所以最好创建一个管理类,用单例模式来进行管理,只创建一个 ImageLoader 实例,然后通过 setLoadStrategy 方法来设置具体的 ILoadStrategy 实现,这样,调用者只需要关心如何使用这个 ImageLoader 实例即可,而不需要关心具体的 ILoadStrategy 实现。
关于ILoadStrategy
由于最终干活的事 ILoadStrategy 的具体实现类,而这个类需要根据调用者传入的参数进行构造,这里利用简单工厂模式来构造,具体实现如下:
1 | public class LoaderStrategyFactory { |
关于LoadConfig
这里的 LoadConfig值的是加载图片的配置,这个类分通用配置和不通框架的具体配置,通用配置在 Base里声明,不通加载库特有的配置在 具体的子类中说明,这样就在保持共性的同时,还兼顾了不通加载库的特性,关于类的具体实现这里就不贴代码了,由于配置项较多,就采用 建造者模式来完成具体 LoadConfig的构造了。
为了避免 每次都要创建 LoadConfig对象,可以创建几个常用的配置对象,缓存在内存中,如默认的配置,这样在 LoadConfig 为空时,可以直接采用 默认的。
总结
通过策略模式来完成具体加载策略的实现,通过建造者模式来完成不通加载配置的构建,通过单例模式来实现加载框架的管理和设置,通过工厂模式来完成 具体策略实例的创建,然后整个封装的基本思想就是 控制反转,尽量达到代码的高内聚低耦合,方便后续维护、扩展。