1.主要涉及到的类,以及该类的具体操作逻辑
1)Picasso、Picasso.Builder Builder是Picasso的内部类,主要作用是用来创建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。
2)RequestCreator、Request、Action、DeferredRequestCreator
RequestCreator:通过picaasso.load()方法创建,RequestCreator内部也有一个Builder,主要作用是通过Builder模式,Builder各种存放设置参数后,创建请求图片的Request、Action和requestKey。最后通过picasso.enqueueAndSubmit(action);回到Picasso在到Dispatcher中。
DeferredRequestCreator:用于延迟创建Request.当在请求是使用了fit()方法,并且ImageView的width 和 height 为零,ImageView会添加ViewTreeObserver.OnPreDrawListener监听,当绘制前获取到宽高,在去创建Request和请求的requestKey。下图picsso.defer方法会缓存DeferredRequestCreator对象。会在picasso.enqueueAndSubmit(action)方法是从map集合中移除。
Request和Action:Request存放的是请求设置的一些配置参数。Action持有Request引用,也弱引用着ImageView,也存放了缓存的配置参数。
3)BitmapHunter 是实现了Runnable接口,当提交的线程池后,当执行该加载线程时,会执行run方法。BitmapHunter的方法,执行了一个hunt()方法。返回一个bitmap。
4)RequestHandler
在BitmapHunter的构造方法中获取了对应的RequestHandler,该类有7个实现类,对应的是资源,asset,网络,文件,media,联系人。
创建picasso对象的时候回创建7种requestHandler,如下图:
5) 网络加载完成之后回调到Dispacher的一些操作
a.缓存到内存当中
b.移除dispatcher中BitmapHunter ,通过handler的hasmessages方法来批量处理一批图片,处理完成之后也马上就会相应的清除。
c.将批量的hunter通过mainThreadHandler发送到Picasso中处理,并清空处理批零缓存的hunter。
d.Picasso收到HUNTER_BATCH_COMPLETE消息后会在hunter.picasso.complete(hunter)调用方法deliverAction方法,将bitmap加载到Action上。这里我们主要看ImageViewAction的complete方法
到此picasso的图片加载流程就到这里了,下边说一下网络层的一些操作
2.网络层的操作
我们知道加载图片在bitmapHunter中的hunt方法执行的。hunt方法中有一个关键的代码,如下:
RequestHandler.Result result =requestHandler.load(data,networkPolicy);
这段代码就是前面我们谈的中requestHandler来加载的,requestHandler在创建bitmapHunder对象的时候,就具体选择出来要使用7中requestHandler中的哪一种,加载完成之后的bitmap就会放在Result中。在下边我主要讲一下NetworkRequestHandler。
从图中我们看到,有去调用了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。