Picasso介绍
https://github.com/square/picasso
Picasso是Android开发中常用的几大图片加载库之一,除此之外常用的还有UIL、Glide、Fresco等。
目前UIL作者已经不再维护,Glide源码比较复杂,Fresco涉及c语言层面。相比之下Picasso写得比较简洁、规范,更好入手分析。
通过分析Picasso源码来对Android的图片加载有更深入的理解。
目前最新版本为2.71828(奇葩的版本号),本文基于此分析。
最新的使用方式为:
1 | PicassoProvider.get().load("url").into(imageview) |
下面就根据这个调用流程来分析其源码。
图示
Picasso的get方法
此前Picasso包括Glide的调用方式都需要通过with(context)方法来传入context,最新版本通过一个get方法即可实现。
项目中单独提供一个picasso-provider库工程实现此方法。
1 | public final class PicassoProvider { |
此处使用双重校验锁来实现Picasso类单例。
context的获取通过PicassoContentProvider类实现:
1 | public final class PicassoContentProvider extends ContentProvider { |
此类在AndroidManifest中注册,因此在App启动的时候,系统就会自动回调PicassoContentProvider 的onCreate方法,因此也就自动获取到了Context。
Picasso的创建
Picasso通过Builder模式创建实例,通过以下这行代码获取实例。
1 | instance = new Picasso.Builder(autoContext).build(); |
Builder类构造函数:
1 | Builder(Picasso picasso) { |
build方法:
1 | public Picasso build() { |
Picasso构造函数:
1 | Picasso(...) { |
Picasso创建分析完毕。
Picasso的load方法
load方法对应不同的重载方法:包括int、String、Object、Uri等,以Uri为例:
1 | public RequestCreator load(@Nullable Uri uri) { |
最终创建并返回一个RequestCreator实例。
1 | RequestCreator(Picasso picasso, @Nullable Uri uri, int resourceId) { |
RequestCreator核心就是创建Request.Builder,即data实例。
RequestCreator创建完成后,内部还包含placeholder、error、fit等方法,可继续链式调用,这里主要分析主流程,不详细赘述。
RequestCreator的into方法
1 | public void into(@NonNull ImageView target, @Nullable Callback callback) { |
createRequest创建Request实例。
1 | private Request createRequest(long started) { |
上述主要分析了PicassoProvider.get().load(“url”).into(imageview)整体流程。
Dispatcher处理请求流程
前面分析into方法的最后,图片以Action的形式加入Picasso请求:
1 | picasso.enqueueAndSubmit(action) |
请求加入Dispatcher中,然后放到Handler进行处理。
1 | void dispatchSubmit(Action action) { |
Dispatcher核心是DispatcherThread、DispatcherHandler、PicassoExecutorService。
DispatcherThread是一个HandlerThread,HandlerThread有自己的内部Looper对象,将Message发送给DispatcherHandler在handleMessage进行处理。
1 | private static class DispatcherHandler extends Handler { |
再来看看Dispathcer的perormSubmit方法。
1 | void performSubmit(Action action, boolean dismissFailed) { |
service即PicassoExecutorService,是Picasso实现基于优先级队列PriorityBlockingQueue的线程池,继承于ThreadPoolExecutor,内部有一个FutureTask实现类PicassoFutureTask。
PicassoFutureTask通过compareTo方法比较请求的优先级,具体实现在其内部持有的BitmapHunter内部。
BitmapHunter是Runnable子类,具体作用就是“狩猎”bitmap,返回一个持有bitmap的Result。
service.submit(hunter)即是将FutureTask提交到线程池处理,返回一个Future,此处之所以用FutureTask,是用于监听hunter是否执行完毕且可以cancel执行。
BitmapHunter其核心是run里的hunt方法。
1 | Result hunt() throws IOException { |
run方法再将处理的结果发送回Dispathcer,例如dispatchComplete和dispatchFailed。
Dispathcer里还维护了一个主线程Handler,mainThreadHandler,在Picasso类实现传入。
前面处理的结果最终会通过一个deliver方法传回mainThreadHandler,通过回调监听返回listener返回给Picasso使用方,即App。
至此,Picasso主要流程分析完毕。