Picasso--设计思路浅析
Picasso结构图
Paste_Image.png
Picasso流程图
Paste_Image.png
Picasso中的核心类包括Picasso、Dispatcher、BitmapHunter、RequestHandler、Request、Action、Cache等。
Picasso类是一个负责图片下载、变换、缓存的管理器,当它收到一个图片下载请求的时候,它会创建Request并提交给Dispatcher。load负责加载网络图片,into负责把图片显示到组件中。
public void into(ImageView target, Callback callback) {
…
ImageViewAction action1 = new ImageViewAction(this.picasso, target, request1, this.memoryPolicy, this.networkPolicy, this.errorResId, this.errorDrawable, requestKey1, this.tag, callback, this.noFade);
this.picasso.enqueueAndSubmit(action1);
}
}
可以看到into最后通过picasso.enqueueAndSubmit提交到队列,每一个请求对应一个action,每个图片都会into到组件中,因此会有很多action交给Picasso执行,这时就需要Dispatcher进行分发和执行。
void enqueueAndSubmit(Action action) {
Object target = action.getTarget();
if(target != null && this.targetToAction.get(target) != action) {
this.cancelExistingRequest(target);
this.targetToAction.put(target, action);
}
this.submit(action);
}
void submit(Action action) {
this.dispatcher.dispatchSubmit(action);
}
Dispatcher是在Picasso被创建前实例化的,并作为picasso的一个成员变量
public Picasso build() {
Context context = this.context;
…
Dispatcher dispatcher = new Dispatcher(context, this.service, Picasso.HANDLER, this.downloader, this.cache, stats);
…
}
在Dispatcher的构造函数中开启了一个消息循环线程DispatcherThread(DispatcherThread是一个HandlerThread,也就是一个带有Looper的线程),之后用DispatcherThread的Looper实例化了一个Handler,用来处理消息循环线程的所有消息。
Dispatcher(Context context, ExecutorService service, Handler mainThreadHandler, Downloader downloader, Cache cache, Stats stats) {
this.dispatcherThread.start();
…
this.handler = new Dispatcher.DispatcherHandler(this.dispatcherThread.getLooper(), this);
…
}
final Dispatcher.DispatcherThread dispatcherThread = new Dispatcher.DispatcherThread();
static class DispatcherThread extends HandlerThread {
DispatcherThread() {
super("Picasso-Dispatcher", 10);
}
}
这样Dispatcher的消息循环机制就建立起来了。
根据上面介绍into->picasso.enqueueAndSubmit->submit-> dispatcher.dispatchSubmit
void dispatchSubmit(Action action) {
this.handler.sendMessage(this.handler.obtainMessage(REQUEST_SUBMIT
, action));
}
可以看到是通过Handler向HandlerThread发消息进行分发的。根据Hander机制,最终消息在Handler的 handlerMessage()回调中被处理, action的其他操作,也通过这种方式进行分发和处理。
public void handleMessage(final Message msg) {
Object info;
BitmapHunter info2;
Action info3;
switch(msg.what) {
case REQUEST_SUBMIT:
info3 = (Action)msg.obj;
this.dispatcher.performSubmit(info3);
break;
…
}
}
action的执行通过dispatcher.performSubmit
void performSubmit(Action action) {
this.performSubmit(action, true);
}
void performSubmit(Action action, boolean dismissFailed) {
//action是否被暂停
if(this.pausedTags.contains(action.getTag())) {
…
} else {
//从hunter map里查找当前action所关联的hunter,有就直接使用
BitmapHunter hunter = (BitmapHunter)this.hunterMap.get(action.getKey());
if(hunter != null) {
…
} else if(this.service.isShutdown()) {
…
} else {
//创建BitmapHunter
hunter = BitmapHunter.forRequest(action.getPicasso(), this, this.cache, this.stats, action);
//提交到线程池中执行
hunter.future = this.service.submit(hunter);
//把此hunter加入到hunter map中
this.hunterMap.put(action.getKey(), hunter);
…
}
}
}
可以看到这里BitmapHunter出场了,忽略掉异常情况,可以看到是由forRequest()创建该action的BitMapHunter,之后提交到线程池中并加入到hunter map中。
再来看BitMapHunter
class BitmapHunter implements Runnable
可以看到BitmapHunter其实是一个Runnable,在线程池上执行的是其run()方法
Bitmap result;
public void run() {
…
this.result = this.hunt();//获得bitmap
if(this.result == null) {//通过dispatcher分发处理
this.dispatcher.dispatchFailed(this);
} else {
this.dispatcher.dispatchComplete(this);
}
…
}
忽略掉异常情况,bitmap是通过hunt这个方法获得的, 然后将结果通过Dispatcher进行分发处理
进入到hunt中看如何获得bitmap
Bitmap hunt() throws IOException {
Bitmap bitmap = null;
…
Result result = this.requestHandler.load(this.data, this.networkPolicy);
if(result != null) {
…
bitmap = result.getBitmap();
…
}
…
}
return bitmap;
}
忽略掉异常情况, Bitmap最终是由BitmapHunter的requestHandler.load()方法获取的, Picasso默认提供了ResourceRequestHandler、ContactsPhotoRequestHandler、MediaStoreRequestHandler、ContentStreamRequestHandler、 AssetRequestHandler、FileRequestHandler、NetworkRequestHandler等7中RequestHandler,用来从不同的来源获取Bitmap。