Picasso源码学习

1.主要涉及到的类,以及该类的具体操作逻辑

1)Picasso、Picasso.Builder  Builder是Picasso的内部类,主要作用是用来创建Picasso对象的。创建对象需要以下几个对象

Picasso源码学习_第1张图片
Picasso对象创建

downloader:可以支持okHttp和HttpURLConnection,如果你的项目引用了okhttp那么就会首先使用,否者就使用HttpURLConnection。

cache:这里的cache是用于内存缓存的,内部使用LinkedHashMap实现的。

service:PicassoExecutorService继承ThreadPoolExecutor,是用于下载图片的线程池。里面实现了根据网络状态来分配多少的线程数,同事也复写了compareTo()方法,实现了线程的优先级。

RequestTransformer:是一个接口,用来修改请求信息(还有点迷糊)。

Stats:我的理解就是内存大小、下载次数、生成内存快照等的统计类。

Dispatcher :通过Handler实现下载任务的分发和回调,Dispatcher扮演者任务下载,以及下载完成回调等枢纽的关键位置。它吃有两个handler,mainThreadHandler和DispatcherHandler。DispatcherHandler的作用主要负责分发加载、回调、写入缓存操作等。mainThreadHandler从Dispatcher中获取回来的的图片信息显示在控件上。以下是Dispatcher将BitmapHunter提交到线程池的关键代码。这里如果已经加载过得hunter会缓存一份在hunterMap中。当hunter加载完图片后会对应移除响应的hunter。

Picasso源码学习_第2张图片
将BitmapHunter提交到线程池加载图片

2)RequestCreator、Request、Action、DeferredRequestCreator

RequestCreator:通过picaasso.load()方法创建,RequestCreator内部也有一个Builder,主要作用是通过Builder模式,Builder各种存放设置参数后,创建请求图片的Request、Action和requestKey。最后通过picasso.enqueueAndSubmit(action);回到Picasso在到Dispatcher中。

Picasso源码学习_第3张图片
enqueueAndSubmit方法

DeferredRequestCreator:用于延迟创建Request.当在请求是使用了fit()方法,并且ImageView的width 和 height 为零,ImageView会添加ViewTreeObserver.OnPreDrawListener监听,当绘制前获取到宽高,在去创建Request和请求的requestKey。下图picsso.defer方法会缓存DeferredRequestCreator对象。会在picasso.enqueueAndSubmit(action)方法是从map集合中移除。

Picasso源码学习_第4张图片
DeferredRequestCreator创建和缓存

Request和Action:Request存放的是请求设置的一些配置参数。Action持有Request引用,也弱引用着ImageView,也存放了缓存的配置参数。

3)BitmapHunter 是实现了Runnable接口,当提交的线程池后,当执行该加载线程时,会执行run方法。BitmapHunter的方法,执行了一个hunt()方法。返回一个bitmap。

4)RequestHandler

在BitmapHunter的构造方法中获取了对应的RequestHandler,该类有7个实现类,对应的是资源,asset,网络,文件,media,联系人。

Picasso源码学习_第5张图片
通过循环获取合适的ReqestHandler

创建picasso对象的时候回创建7种requestHandler,如下图:

Picasso源码学习_第6张图片
创建所有的requestHandler

5) 网络加载完成之后回调到Dispacher的一些操作

a.缓存到内存当中

Picasso源码学习_第7张图片
dispatcher缓存bitmap到内存

b.移除dispatcher中BitmapHunter ,通过handler的hasmessages方法来批量处理一批图片,处理完成之后也马上就会相应的清除。

Picasso源码学习_第8张图片
批量处理hunter

c.将批量的hunter通过mainThreadHandler发送到Picasso中处理,并清空处理批零缓存的hunter。

Picasso源码学习_第9张图片
清理批量处理时缓存的hunter

d.Picasso收到HUNTER_BATCH_COMPLETE消息后会在hunter.picasso.complete(hunter)调用方法deliverAction方法,将bitmap加载到Action上。这里我们主要看ImageViewAction的complete方法

Picasso源码学习_第10张图片
抽象的acition加载完成
Picasso源码学习_第11张图片
action实现类ImageViewAction的complete

到此picasso的图片加载流程就到这里了,下边说一下网络层的一些操作

2.网络层的操作

我们知道加载图片在bitmapHunter中的hunt方法执行的。hunt方法中有一个关键的代码,如下:

RequestHandler.Result result =requestHandler.load(data,networkPolicy);

这段代码就是前面我们谈的中requestHandler来加载的,requestHandler在创建bitmapHunder对象的时候,就具体选择出来要使用7中requestHandler中的哪一种,加载完成之后的bitmap就会放在Result中。在下边我主要讲一下NetworkRequestHandler。

Picasso源码学习_第12张图片
NetworkRequestHandler的load方法

从图中我们看到,有去调用了downloader的load方法。在前边我们知道有两种downloader。OkHttpDownloader和UrlConnectionDownloader。具体使用哪种,就看你项目中是否使用okHttp网络加载框架,如果使用了就会优先使用OkHttpDownloader,否则就是用UrlConnectionDownloader。通过load方法返回一个Response,我们就可以通过Response获取到夹杂回来的图片流信息。

3.总结:

1、加载内存缓存的地方有两处,一个是在RequestCreator中,一处是下bitmapHunter的hunt()方法中。

2、dispacher将加载完成的bitmap通过handler回到主线程中。

3、简单写一个加载链,一个简要的加载流程。

Picasso-->picasso.load-->RequestCreator-->requestCreator.into-->picasso-->Dispatcher-->dispatcher.performSubmit-->BitmapHunter-->ExecutorService-->bitmapHunter.run-->dispatcher-->mainThreadHandler-->picasso.complete-->Aciton。

你可能感兴趣的:(Picasso源码学习)