Picasso源码完全解析(二)--Picasso实例的创建
Picasso源码完全解析(三)--Request和Action的创建
Picasso源码完全解析(五)--图片的获取(BitmapHunter)
Picasso源码完全解析(六)--请求的取消、暂停、和恢复
Picasso源码完全解析(七)-- CleanupThread 取消请求
Picasso源码完全解析(四)--Action分发和执行
上节讲到 我们的每个图片请求最后生成一个Action被提交给Picasso执行,那么那么多的Action Picasso是怎么执行的呢?
void enqueueAndSubmit(Action action) {
Object target = action.getTarget();
if (target != null && targetToAction.get(target) != action) {
// This will also check we are on the main thread.
cancelExistingRequest(target);
targetToAction.put(target, action);
}
submit(action);
}
void submit(Action action) {
dispatcher.dispatchSubmit(action);
}
可以看到最终Action是通过Dispatcher进行分发的和执行的,下面详细介绍Dispatcher是如何进行消息分发和执行的。
消息循环的建立
首先来看看Dispatcher的主要成员变量:
private static final int RETRY_DELAY = 500;
private static final int AIRPLANE_MODE_ON = 1;
private static final int AIRPLANE_MODE_OFF = 0;
static final int REQUEST_SUBMIT = 1;
static final int REQUEST_CANCEL = 2;
static final int REQUEST_GCED = 3;
static final int HUNTER_COMPLETE = 4;
static final int HUNTER_RETRY = 5;
static final int HUNTER_DECODE_FAILED = 6;
static final int HUNTER_DELAY_NEXT_BATCH = 7;
static final int HUNTER_BATCH_COMPLETE = 8;
static final int NETWORK_STATE_CHANGE = 9;
static final int AIRPLANE_MODE_CHANGE = 10;
static final int TAG_PAUSE = 11;
static final int TAG_RESUME = 12;
static final int REQUEST_BATCH_RESUME = 13;
private static final String DISPATCHER_THREAD_NAME = "Dispatcher";
private static final int BATCH_DELAY = 200; // ms
final DispatcherThread dispatcherThread;//消息循环线程
final Context context;
final ExecutorService service;//执行线程池
final Downloader downloader;//下载器
final Map<String, BitmapHunter> hunterMap;
final Map<Object, Action> failedActions;
final Map<Object, Action> pausedActions;
final Set<Object> pausedTags;
final Handler handler;//消息处理者
final Handler mainThreadHandler;
final Cache cache;//内存缓存
final Stats stats;//统计快照
final List<BitmapHunter> batch;
final NetworkBroadcastReceiver receiver;//网络状况广播接受者
final boolean scansNetworkChanges;
boolean airplaneMode;
主要的成员变量如上面注释所示。
在看看Dispatcher的实例化时机。
public Picasso build() {
Context context = this.context;
if (downloader == null) {
downloader = Utils.createDefaultDownloader(context);
}
if (cache == null) {
cache = new LruCache(context);
}
if (service == null) {
service = new PicassoExecutorService();
}
if (transformer == null) {
transformer = RequestTransformer.IDENTITY;
}
Stats stats = new Stats(cache);
Dispatcher dispatcher = new Dispatcher(context, service, HANDLER, downloader, cache, stats);
return new Picasso(context, dispatcher, cache, listener, transformer, requestHandlers, stats,
defaultBitmapConfig, indicatorsEnabled, loggingEnabled);
}
可以看到Dispatcher是在Picasso被创建前实例化的,并作为picasso的一个成员变量。
再看看Dispatcher的构造函数:
Dispatcher(Context context, ExecutorService service, Handler mainThreadHandler,
Downloader downloader, Cache cache, Stats stats) {
this.dispatcherThread = new DispatcherThread();
this.dispatcherThread.start();
Utils.flushStackLocalLeaks(dispatcherThread.getLooper());
this.context = context;
this.service = service;
this.hunterMap = new LinkedHashMap<String, BitmapHunter>();
this.failedActions = new WeakHashMap<Object, Action>();
this.pausedActions = new WeakHashMap<Object, Action>();
this.pausedTags = new HashSet<Object>();
this.handler = new DispatcherHandler(dispatcherThread.getLooper(), this);
this.downloader = downloader;
this.mainThreadHandler = mainThreadHandler;
this.cache = cache;
this.stats = stats;
this.batch = new ArrayList<BitmapHunter>(4);
this.airplaneMode = Utils.isAirplaneModeOn(this.context);
this.scansNetworkChanges = hasPermission(context, Manifest.permission.ACCESS_NETWORK_STATE);
this.receiver = new NetworkBroadcastReceiver(this);
receiver.register();
}
可以看出Dispatcher在实例化的时候主要是做了一些初始化的操作,最重要的是开启了一个消息循环线程DispatcherThread
static class DispatcherThread extends HandlerThread {
DispatcherThread() {
super(Utils.THREAD_PREFIX + DISPATCHER_THREAD_NAME, THREAD_PRIORITY_BACKGROUND);
}
}
DispatcherThread其实是一个HandlerThread,也就是一个带有Looper的线程。
this.handler = new DispatcherHandler(dispatcherThread.getLooper(), this);
紧接着用DispatcherThread的Looper实例化了一个Handler,用来处理消息循环线程的所有消息。
到此Dispatcher的消息循环机制就建立起来了。
Action的分发 和 处理
由上面的分析可以知道,当Dispatcher被创建后,就建立一个消息循环线程,通过这个HandlerThread关联的Handler可以进行消息的分发和处理。
我们提交给picasso的所有Action都是这样被分发的:
dispatcher.dispatchSubmit(action);
再看看dispatcher.dispatchSubmit()
void dispatchSubmit(Action action) {
handler.sendMessage(handler.obtainMessage(REQUEST_SUBMIT, action));
}
可以看到是通过Handler向HandlerThread发消息进行分发的。
根据Hander机制,最终消息在Handler的 handlerMessage()回调中被处理:
case REQUEST_SUBMIT: {
Action action = (Action) msg.obj;
dispatcher.performSubmit(action);
break;
}
最后消息的执行是通过dispatcher.performSubmit()得到执行的。
类似的,对Action的其他操作,也是通过这种机制分发和处理的。