上节我们分析了应用进程中的Looper和MessageQueue创建过程,接下来我们来看看Message是如何发送到当前的MessageQueue上并且它是如何得到处理的。
一、Message的发送过程
发送一个Message对于应用来说,非常简单,就是调用handler.sendMessage方法,就可以将一个封装好的Message发送出去了,或者调用handler.post(Runnable r)也可以,两种调用往下的实现是完全一样的。我们就以sendMessage为入口来看一下Message发送的过程。该方法的实现在Handler.java类中,目录路径为frameworks\base\core\java\android\os\Handler.java,sendMessage方法的源码如下:
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);
}
该方法的第一句就是给当前的message的target赋值,表示该message最终由谁处理,一般我们都会构造自己的handler,所以最终该消息得到分发的时候,目标就是我们重写的handler了,接着调用queue局部变量的enqueueMessage方法来将该message入队,queue局部变量的类型为MessageQueue,它指向的就是执行当前逻辑的Looper对象的mQueue成员变量,也就是上一节我们分析Looper创建过程中创建好的。MessageQueue类的目录路径为frameworks\base\core\java\android\os\MessageQueue.java,enqueueMessage方法的源码如下:
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(TAG, e.getMessage(), e);
msg.recycle();
return false;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
该方法中前面的逻辑的目的就是寻找到一个合适的位置,把当前的message对象挂载进去,上一节我们已经说了MessageQueue类的mMessages成员变量,它的类型为Message,而Message又是一个单向链表,可以不断的往它的成员变量next上指定下一个message,所以只要发送message,就会不断的往上面一个合适的节点挂载。挂载完成后根据局部变量needWake的值来判断是否要唤醒当前的Looper循环,如果我们发送的message需要延迟,而且时间没到