`
heyixian
  • 浏览: 12665 次
社区版块
存档分类
最新评论

图片缓存库之深度剖析

阅读更多

 

 

 

一、 本文由来:

让更多的人审核和发现BUG,一直是本人所崇尚的目标。经历了5年的发展,Android中也有很多质量很高的开源项目。UnversalImageLoader(统一图片缓存加载库),目前最流行功能最强大的图片缓存库。本文致力于在学习中挖掘和探讨其代码和设计,或者说这是介绍怎样建设一个受欢迎的库。

项目地址:https://github.com/nostra13/Android-Universal-Image-Loader

 

二、功能以及设计:

良好的接口,丰富的核心,强大的扩展。

Imageloader对外接口使用了java工具类非常常见的单例模式,获取单例对象之后,调用displayImage方法就可以对一个已存在的ImageView加载一个远程URL图片

不难发现这也是门面模式一个很好的应用,将逻辑和控制置于ImageloaderEngine中,自己保存了配置对象ImageLoaderConfiguration

类关系如下:



  

在使用Imageloader去显示图片之前,必须先调用初始化方法init(),传入一个配置对象.初始化代码示例:



  

这又是熟悉的建造者模式。Imageloader的配置和默认显示的配置都是通过Builder模式构建起来。通过研究内部实现可以发现,没有设置的选项,都会使用库本身默认的配置。

 

ImageloaderEngine类是库的核心,负责调度各个模块,这又是一个中介者模式。

ImageloaderEngine类中聚合了Task对象,LoadAndDisplayProgressAndDisplay的任务,根据名字就可以知道其功能。类关系如下:



  

ProgressAndDisplayTask相比LoadAndDisplay多了一个显示加载中图片的功能,只是在LoadAndDisplay之前多做了一步设置加载中图片的操作。

以下是LoadandDisplayTask的类关系视图:



  

如图,LoadAndDisplayTask类根据配置,调用ImageDownloaderImageDecoder进行图片的下载和解码,最后通过DisplayImageOptions中的bitmapDisplayer对象对imageView进行设置图片的操作。当然,这一过程中,不断的通过ImageLoader这个监听对外汇报任务状态。真真切切的观察者模式,一举一动尽在掌握。

到这里主体的框架已经介绍完毕。是否感觉就这么回事,这一流程不就是普普通通的图片缓存库该做的事情么。其实它真正的妙处在于面向接口的设计,如上图,ImageDecoderImageDownloader就只是一个接口关联。并没有关系具体实现类,本库中提供了多种多样的实现类。如图:



  

通过初始化的配置,根据不同的网络状况选择不同的Downloader,自由的拆卸和组合,让人用起来得心应手。

观察上图,或许读者有一个疑问,BitmapDisplayer为何置于DisplayOptions中而不是LoadAndDisplayTask的一部分,这也是作者的一个设计妙处。首先我们回到一开始的接口。

public void displayImage(String uri, ImageView imageView, DisplayImageOptions options,ImageLoadingListener listener);

用户使用这个接口,可以对每一次的加载图片操作进行不同的配置,不同的BitmapDisplayer,库中也提供了多种BitmapDisplayer接口的实现:



  

甚至可以自定义,使用自己实现的BitmapDisplayer,现阶段做的项目就通过实现自定义的Displayer实现了显示图片的怦然心动动画效果。

实现代码如下:



  

 

 

 

三、总结:

UnversalImageLoader中还有许多值得我们学习的地方,譬如多线程中锁ReetranLock类的使用和异常处理。本文的重点是介绍其设计中合理性,技术要点将在新的文档实践和介绍,这里暂不花费篇幅阐述

使用开源库不应该只满足其如何使用,更应该了解并且探究它。我们的目标并不是重复发明轮子,但是发明轮子的能力是必须要有的。

 

  • 大小: 69.2 KB
  • 大小: 23.1 KB
  • 大小: 54.3 KB
  • 大小: 77.2 KB
  • 大小: 3.1 KB
  • 大小: 2.7 KB
  • 大小: 45.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics