本篇內(nèi)容很簡單溯饵,純屬記錄方便日后記憶廷痘。
Handler消息機制細節(jié)就不多說了套耕。我們知道尘应,Looper不停的從消息隊列中取出Message惶凝,然后分發(fā)給對應的Handler去處理。Handler附屬于哪個線程取決于Handler構(gòu)造時對應的 Looper附屬的線程犬钢,即Handler構(gòu)造的時候就確定了苍鲜,它終究要為哪個線程的消息分發(fā)后的處理進行服務,也就決定了執(zhí)行 Handler#dispatchMessage
所在的線程玷犹。
消息分發(fā)
Message和Handler關聯(lián)的方式很簡單混滔,用哪個Handler發(fā)送的消息,就用哪個Handler進行任務處理歹颓。最終會調(diào)用 Handler#dispatchMessage
進行消息處理:
public class Handler{
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
}
我們看到無論如何會有一個 Message 對象分發(fā)過來坯屿,Message對象可以選擇性的攜帶一些數(shù)據(jù)。
在 dispatchMessage
進行分發(fā)的時候分了3種情況:
1晴股、如果 msg對象 中有 callback 屬性愿伴,直接調(diào)用 callback#run
方法 「callback是一個實現(xiàn)了Runnable接口的實例」
2、Handler 對象中有 mCallback屬性电湘,直接調(diào)用 mCallback#handleMessage
隔节,如果mCallback#handleMessage
返回為true,分發(fā)結(jié)束寂呛;
3怎诫、如果mCallback#handleMessage
返回false,則繼續(xù)執(zhí)行 Handler#handleMessage
進行消息分發(fā)贷痪。
這里說明一下mCallback幻妓,不是Runnable類型,而是實現(xiàn)了如下類型「Callback」的實例劫拢,區(qū)別是有入?yún)⒑头祷刂怠?/p>
public interface Callback {
boolean handleMessage(@NonNull Message msg);
}
Message發(fā)送
針對這種情況肉津,在發(fā)送Message的時候演化了很多種形式:【這里簡單列幾種】
首先定義Handler:
class MyHandler : Handler {
constructor() : super()
constructor(callback: Callback) : super(callback)
override fun handleMessage(msg: Message) {
Log.e(MainActivity::class.java.name, "Handler - handleMessage: ${msg.what}")
}
}
一强胰、 Handler#postXXX(@NonNull Runnable r)
private val handler0 = MyHandler()
handler0.post { // kotlin : lambda表達式
Log.e(MainActivity::class.java.name, "Runnable - run")
}
最終消息分發(fā)回走上邊的第一種
情況,直接結(jié)果:
MainActivity: Runnable - run
二妹沙、 Handler#sendXXX(XXX)
private val handler1 = MyHandler(Handler.Callback {msg ->
Log.e(MainActivity::class.java.name, "Callback - handleMessage: ${msg.what}")
true //這里
})
handler1.sendEmptyMessage(11)
最終消息分發(fā)回走上邊的第二種
情況偶洋,直接結(jié)果:
MainActivity: Callback - handleMessage: 11
三
private val handler2 = MyHandler(Handler.Callback {msg ->
Log.e(MainActivity::class.java.name, "Callback - handleMessage: ${msg.what}")
false //這里
})
handler2.sendEmptyMessage(11)
最終消息分發(fā)回走上邊的第三種
情況,直接結(jié)果:
MainActivity: Callback - handleMessage: 11
MainActivity: Handler - handleMessage: 11
總結(jié):總體來說 post 的參數(shù)是Runnable距糖,send的參數(shù)有一部分是 Message玄窝。不論哪種情況都會最終構(gòu)建一個Message對象,然后發(fā)送到對應線程的消息隊列中悍引。
還記得 Activity#runOnUiThread 方法的實現(xiàn)恩脂,也是使用了post的方法:
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}