Android Handler之消息如何回到Handler(三)
续上两篇
有关Handler你想要的都在这里了(一)
有关Handler你想要的都在这里了(二)
上篇我们讲到了当我们调用handler.sendMessage()最终的执行效果是在MessageQueue中插入了一条消息,然后代码无法跟踪了,给我们的源码阅读带来了困难,因为我们的思路断了,接下来怎么办呢?
还记得我们在有关Handler你想要的都在这里了(一)中的第四部分怎么从主线程发送消息到子线程?(虽然这种应用场景很少)中的示例代码吗?
示例代码中有这么一行代码
//启动Looper循环
Looper.loop();
我们为什么要写这一行代码呢?
这个时候就要静下心来想一下了,我们的Message已经存到了MessageQueue中,那么是不是接下来就应该取消息并且处理消息了?带着这样的疑问,我查看了loop()方法的源码
public static void loop() {
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
try {
msg.target.dispatchMessage(msg);
}
}
}
同样的,为了降低阅读难度,我删掉了大部分的代码,只留下了这么几行核心代码,现在我们来看这几行代码的逻辑
这是一个死循环
这个循环的目的是从MessageQueue中取出消息
取消息的方法是MessageQueue.next()方法
取出消息后调用message.target对象的dispatchMessage()方法分发消息
循环跳出的条件是MessageQueue.next()方法返回了null
这也解释了为什么在子线程中要手动调用Looper.loop()方法
不过,看到这里我们应该自然会想到,message.target.是哪个对象?
该对象的dispatchMessage()方法都做了什么操作?
带着疑问,我们进入Message类中去寻找target
public final class Message implements Parcelable {
/*package*/ int flags;
/*package*/ long when;
/*package*/ Bundle data;
/*package*/ Handler target;
/*package*/ Runnable callback;
// sometimes we store linked lists of these things
/*package*/ Message next;
}
看到了吧,Message类中有一个成员变量 target,而这个target是一个Handler,也就是说,在Looper从MessageQueue中取出Message之后,调用了Handler的dispatchMessage()方法。
这里我们不禁要问,这个target指向了哪个Handler?
带着这个疑问,我翻遍了Message类,也没有看到我想要的答案。此时我就想,既然Handler发送了消息就能接收到消息,那么会不会是在发送消息的途中发生了什么细节是我不知道的,那么我只好仔细看发送消息过程中的代码,终于让我发现了这个
//Handler的方法
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
在这个方法的第一行代码就是,将message的target属性赋值为发送message的handler自身。如果读者忘记了这个方法的调用时机,请仔细参阅本系列博客一、二。
也就是说,Looper取出消息后,调用了发送消息的Handler的dispatchMessage()方法,并且将message本身作为参数传了回去。到此时,代码的执行逻辑又回到了Handler中。
接着看handler的dispatchMessage()方法
/**
*handler的方法
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
看到这里面一个我们非常熟悉到方法了没有?—handleMessage()方法,对,这个方法就是我们经常要重写的handleMessage()方法,也是我们处理消息时候的逻辑。
到这里,Handler机制工作的主要流程就完成了。
接下来,我们就应该慢慢回答有关Handler的问题了。
推荐阅读
-
Android编程开发之seekBar采用handler消息处理操作的方法
-
Android编程开发之seekBar采用handler消息处理操作的方法
-
android线程消息机制之Handler详解
-
Android Handler之消息循环的深入解析
-
android线程消息机制之Handler详解
-
Android Handler之消息循环的深入解析
-
Android Studio 之 Android消息机制 之简单Demo --- 使用Handler和Message类来完成消息传递
-
Android消息机制三剑客之Handler、Looper、Message源码分析(一)
-
Android消息机制原理,仿写Handler Looper源码解析跨线程通信原理--之仿写模拟Handler(四)
-
Android AOSP 6.0.1 Handler 如何发送和处理消息?