Handler訊息機制之流程解析
阿新 • • 發佈:2019-01-06
Hanlder中Messsage的傳送和處理過程
Handler.sendMessage()
-->MessageQueue.enqueueMessage()
-->Looper.next()
-->MessageQueue.next()
-->Handler.dispatchMessage()
通過一張圖片來加深理解:
Handler類原始碼分析
構造方法和屬性:
final Looper mLooper; final MessageQueue mQueue; final Callback mCallback; final boolean mAsynchronous; IMessenger mMessenger; public Handler() { this(null, false); } public Handler(Callback callback) { this(callback, false); } public Handler(Looper looper) { this(looper, null, false); } public Handler(Looper looper, Callback callback) { this(looper, callback, false); } public Handler(boolean async) { this(null, async); } public Handler(Callback callback, boolean async) { mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = callback; mAsynchronous = async; } public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
Message的傳送過程:
先來,檢視sendMessage()
: 從message物件新增進去,計算執行時間,最終新增到MessageQueue中。
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) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); 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); }
再來,看下post()
方法:
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;//將Runnable與Message繫結
return m;
}
從以上可知,兩個方法最終都是轉成Message物件,放到MessageQueue佇列中,等待執行。
Message分發處理的過程:
檢視Looper.looo()方法呼叫的dispatchMessage()
:
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
//先呼叫Handler的CallBack介面
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
//後呼叫
handleMessage(msg);
}
}
//執行Message中Runnable介面的run()
private static void handleCallback(Message message) {
message.callback.run();
}
public void handleMessage(Message msg) {
}
Handler類中的dispatchMessage()按以下順序來分發一個訊息:
- 首先,若是Message中callback介面(實際上為Runnable介面)不為空,則執行callback介面物件的run()
- 其次,若是Handler的mCallback不為空,則呼叫CallBack的
handleMessage()
- 最後才是,呼叫Handler的
handleMessage()