Android 源码解析: 图片加载库Picasso 3 核心类

本文介绍了Android平台上的图片加载库Picasso的核心组件及其工作流程。Picasso通过一系列设计良好的类,如RequestCreator、BitmapHunter等,实现了高效的图片加载、缓存及处理。此外,还详细解释了缓存机制、图片请求的封装、异步处理等方面。
Android 源码解析: 图片加载库Picasso 3 核心类

Picasso类库中各个类的设计:
Picasso是Picasso框架的入口,同时也负责初始化各种工作的子线程,工作的实例;RequestCreator则是对任务的描述;而BitmapHunter则是一个具体的工作的线程,接受Picasso中配置好的调度池的调度同时负责知道对应的ReqeustHandler去执行数据请求,并将结果解析为图片,还可以进行一些图片的处理(Transformation),在Picasso当中,任务调度用的类是Dispatcher。
      Picasso的主要流程是:
  1. 初始化Picasso,实例化其唯一的对象。
  2. 根据传入的Url、File、resource Id,构建ReqeustCreator对象
  3. 根据ReqeustCreator构建Request对象,同时根据Reqeust属性,尝试从Cache中访问数据
  4. Cache Hit,则通过回调,设置Target或者ImageView,完成该Reqeust
  5. 如果Cache Miss,那么则构建相应的Action,并提交到DispatcherThread当中。
  6. Dispatcher中的Handler接收到相应的Message,调用dispatcher.performSubmit(action)进行处理。
  7. 创建BitmapHunter对象,并提交到PicassoExecutorService线程池
  8. 再次检查Memory Cache中已经有缓存,如果Hit,则读取缓存中的Bitmap
  9. 如果Cache miss,则交给Action对应的ReqeustHandler进行处理,比如网络请求,或者从File读取图片
  10. 返回结果之后,通知Dispatcher中的Handler处理结果。
  11. DispatcherThread中将BitmapHunter的结果打包(batch),最快200ms打包一次。通知主线程HANDLER进行处理
  12. 主线程HANDLER接收打包的BitmapHunter,对最后的结果进行分发。
  Picasso架构图如下图:图片来自网络



Cache,缓存类

LruCacha,主要是get和set方法,存储的结构采用了LinkedHashMap,这种map内部实现了lru算法(Least Recently Used 近期最少使用算法)。
因为会涉及多线程,所以在存取的时候都会加锁。而且每次set操作后都会判断当前缓存区是否已满,如果满了就清掉最少使用的图形。详见LruCachad的private void trimToSize(int maxSize)方法。

Request,操作封装类


所有对图形的操作都会记录在这里,供之后图形的创建使用,如重新计算大小,旋转角度,也可以自定义变换,只需要实现Transformation,一个bitmap转换的接口。
/** Image transformation. */
public interface Transformation {
  /**
   * Transform the source bitmap into a new bitmap. If you create a new bitmap
   * instance, you must call {@link android.graphics.Bitmap#recycle()} on
   * {@code source}. You may return the original if no transformation is
   * required.
   */
  Bitmap transform(Bitmap source);

  /**
   * Returns a unique key for the transformation, used for caching purposes. If
   * the transformation has parameters (e.g. size, scale factor, etc) then these
   * should be part of the key.
   */
  String key();
}
当操作封装好以后,会将Request传到另一个结构中Action。

Action 类

Action代表了一个具体的加载任务,主要用于图片加载后的结果回调,有两个抽象方法,complete和error,也就是当图片解析为bitmap后用户希望做什么。最简单的就是将bitmap设置给imageview,失败了就将错误通过回调通知到上层。
ImageViewAction实现了Action,在complete中将bitmap和imageview组成了一个PicassoDrawable,里面会实现淡出的动画效果。
有了加载任务,具体的图片下载与解析是在哪里呢?这些都是耗时的操作,应该放在异步线程中进行,就是下面的BitmapHunter。

BitmapHunter类

BitmapHunter是一个Runnable,其中有一个decode的抽象方法,用于子类实现不同类型资源的解析
还有一个hunt()方法,内部调用了requestHandler的load()方法,用于实现具体图片的网络下载。
参见源码:可以看到,在decode生成原始bitmap,之后如果需要,可以使用BitmapHunter提供的transformResult()和applyCustomTransformations()方法进行转换。最后在将最终的结果传递到上层dispatcher.dispatchComplete(this)。

Dispatcher类 任务调度器

在bitmaphunter成功得到bitmap后,就是通过dispatcher将结果传递出去的,当然让bitmaphunter执行也要通过Dispatcher。
Dispatcher内有一个HandlerThread(DispatcherThread extends HandlerThread),所有的请求都会通过这个thread转换,也就是请求也是异步的,这样应该是为了Ui线程更加流畅,同时保证请求的顺序。

首先是外部调用的是dispatchXXX()方法,然后通过handler将请求转换到对应的performXXX()方法。
最后,将通过action得到具体的BitmapHunder,然后交给ExecutorService执行。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值