Before
Lopper
是跨進(jìn)程的關(guān)鍵類寞酿,閱讀本文之前最好先熟悉Looper
,MessageQueue
為好;
先看源碼
public class Handler {
final MessageQueue mQueue;
public final boolean sendMessage(Message msg) {
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis){
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);//回調(diào)到熟悉的方法啦
}
}
}
分析
- 由熟悉的
sendMessage
開始徽千,最后都是調(diào)用enqueueMessage
方法忠藤,而最終還是調(diào)用MessageQueue
類的enqueueMessage
方法(點(diǎn)我),到此為止我們一般都是在新線程調(diào)用; - 接下來
Looper
類的loop
方法會(huì)在當(dāng)前線程(如果是更新UI則在主線程)從MessageQueue
中獲取最新消息真竖,通過msg.target.dispatchMessage(msg);
調(diào)用到Handler
中來(上述代碼)儡蔓,然后調(diào)用到handlemessage(msg)
我們就熟悉啦; - 由此疼邀,Handler跨線程最重要的是在當(dāng)前線程(初始化
Handler
的線程)進(jìn)行loop
輪詢,而變量是可以在不同線程訪問·的召锈,所以Handler
可以在其他線程向MessageQueue
中插入數(shù)據(jù)旁振,而loop
則在當(dāng)前線程不斷去取數(shù)據(jù),取得數(shù)據(jù)就回調(diào)涨岁,達(dá)到跨線程的目的拐袜;