本篇内容很简单,纯属记录方便日后记忆。
Handler消息机制细节就不多说了。我们知道,Looper不停的从消息队列中取出Message,然后分发给对应的Handler去处理。Handler附属于哪个线程取决于Handler构造时对应的 Looper附属的线程,即Handler构造的时候就确定了,它终究要为哪个线程的消息分发后的处理进行服务,也就决定了执行 Handler#dispatchMessage
所在的线程。
消息分发
Message和Handler关联的方式很简单,用哪个Handler发送的消息,就用哪个Handler进行任务处理。最终会调用 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 对象分发过来,Message对象可以选择性的携带一些数据。
在 dispatchMessage
进行分发的时候分了3种情况:
1、如果 msg对象 中有 callback 属性,直接调用 callback#run
方法 「callback是一个实现了Runnable接口的实例」
2、Handler 对象中有 mCallback属性,直接调用 mCallback#handleMessage
,如果mCallback#handleMessage
返回为true,分发结束;
3、如果mCallback#handleMessage
返回false,则继续执行 Handler#handleMessage
进行消息分发。
这里说明一下mCallback,不是Runnable类型,而是实现了如下类型「Callback」的实例,区别是有入参和返回值。
public interface Callback {
boolean handleMessage(@NonNull Message msg);
}
Message发送
针对这种情况,在发送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")
}
最终消息分发回走上边的第一种
情况,直接结果:
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)
最终消息分发回走上边的第二种
情况,直接结果:
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)
最终消息分发回走上边的第三种
情况,直接结果:
MainActivity: Callback - handleMessage: 11
MainActivity: Handler - handleMessage: 11
总结:总体来说 post 的参数是Runnable,send的参数有一部分是 Message。不论哪种情况都会最终构建一个Message对象,然后发送到对应线程的消息队列中。
还记得 Activity#runOnUiThread 方法的实现,也是使用了post的方法:
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}