打造自己的Android-Universal-Image-Loader

之前的文章了,一直放在 github 上,打算慢慢都放到上来。

最近阅读了Android-Universal-Image-Loader的源码,又正在学习设计模式,就写一个ImageLoader练练手。

大概分为以下几个步骤吧,

  • 简述下图片加载器的思路
  • 简要介绍一下Android-Universal-Image-Loader源码
  • 在阅读源码的基础上搭建我们的ImageLoader架构,其中穿插一些自己对设计模式的理解
  • 编码实现

简述图片加载器的思路

个人理解中,项目中使用图片加载器的原因主要是能提高图片加载速度,节省用户流量,防止大图片引发OOM,大部分实现方法就是采用三级缓存,网络加载-内存缓存-磁盘缓存,加载时先在内存缓存中查找,找到直接加载,没有找到再到磁盘缓存中查找,并加载到内存缓存中,如果都没有找到则从网络下载,并缓存到内存和磁盘中。加载到图片后根据实际需要对图片进行处理并展示。这就是图片加载的原理。

打造自己的Android-Universal-Image-Loader_第1张图片
加载原理.png

简要介绍一下Android-Universal-Image-Loader的实现。

网上有很多关于Android-Universal-Image-Loader源码解析,这里只简要介绍一下。
Android-UIL中最主要的函数就是Imageloader.displayImage();下面流程图显示了整个调用流程

Android-UIL中主要有几个重要的类:
** ImageLoader **
图片加载等主要调用的类,使用了单例。
主要成员变量

  • ImageLoaderConfiguration configuration; // 保存主要的配置 用了Builder模式
  • ImageLoaderEngine engine; // 用于派发异步任务
  • ImageLoaderListener listener; // 回调监听接口
  • ImageLoader instance; // 单例实例

主要函数

  • init(); // 主要用于初始化ImageLoader, 设置Configuration以及初始化engine
  • displayImage(); // 加载图片并显示到 view 中
  • loadImage(); // 加载图片到缓存中并调用回调接口,并不显示,其最后还是调用了displayImage(),其实最重要的就是displayImage()了,其中主要调用了 ProcessAndDisplayTask 和 LoadAndDisplayTask 的run 函数,具体的加载过程可以看看上面的流程图再结合代码看一下。

ImageLoaderConfiguration
配置信息类,保存了配置信息,用了 Builder 模式
主要成员变量

  • MemoryCache
  • DiskCache
  • ImageDownloader
  • ImageDecoder
  • DisplayImageOptions
    等等,可以参考源码看一下,主要是保存之后在ImageLoader中调用

主要函数
*createDefault(); // 返回一个默认的 Builder

**ImageLoaderEngine **
将任务分发到具体的线程池中
主要成员变量
主要就是三个线程池

  • Executor taskExecutor; // 用于从源获取图片的线程池
  • Executor taskExecutorForCachedImages; // 从缓存池中获取图片的线程池
  • Executor taskDistributor; // 分发任务的线程池,把任务分发到上面两个线程池中

主要函数

  • submit(); // 提交任务线程

** ProcessAndDisplayTask **
处理图片并显示
主要函数
**run(); // 此函数中主要有两个处理步骤,1. 调用BitmapProcessor对bitmap进行处理 2. 调用DisplayBitmapTask 显示图片,主要的逻辑又转移到了DisplayBitmapTask的run函数中。

** LoadAndDisplayTask **
加载图片并显示
主要函数

  • run(); // 先监测memoryCache中是否缓存有图片,有的话直接调用DisplayBitmapTask进行显示,没有的话从diskCache中加载,diskCache中也没有的话就从网络或者其他源进行加载。

** DisplayBitmapTask **
显示图片
主要函数

  • run(); // 直接调用Displayer的display函数,之后调用回调函数listener.onLoadingComplete()

** Displayer **
显示器接口,
主要函数

  • display();

** MemoryCache **
内存缓存
主要函数

  • put();
  • get();
  • remove();
  • keys();
  • clear();

** DiskCache **
内存卡缓存
主要函数

  • getDirectory();
  • get();
  • save();
  • remove();
  • close();
  • clear();

** ImageDownloader **
加载指定源的图片流
主要函数

  • getStream();

总结一些用到的设计模式

  • 六大设计原则
    单一职责
    开闭原则
    里氏替换
    依赖倒置
    接口隔离
    迪米特法则
  • 单例模式
  • Builder模式
  • 外观模式
  • 工厂模式

设计整体框架

项目目录如下:

打造自己的Android-Universal-Image-Loader_第2张图片
项目目录.png

下面是各个类的一些主要成员变量和成员函数

ImageLoader

  • ImageConfig
  • ImageEngine
  • ImageLoader instance
  • displayImage()
  • loadImage()

ImageEngine

ThreadPool

  • submit()

LoadAndDisplayTask

  • run()

DisplayTask

  • run()

ImageConfig
Decoder
Loader
Displayer
HttpConnection
ThreadPool
MemoryCache
DiskCache
Builder

ImageConfigFactory

  • getDefaultXXX()
  • Decoder
  • decode()
  • Displayer
  • display()

Loader

  • load()

具体编码如下

ImageLoader地址

你可能感兴趣的:(打造自己的Android-Universal-Image-Loader)