3.MessageQueue
Android Handler机制源码浅析(上):https://blog.csdn.net/XCF95319605/article/details/81080939
MessageQueue即消息队列,主要的作用是存放消息,MessageQueue最重要的操作就是插入消息和读取消息(移除消息),从handler的源码分析中我们已经知道,MessageQueue是通过他的enqueueMessage方法向队列中插入一条消息,在Looper中又是通过MessageQueue的next方法来获取到消息,所以MessageQueue是通过enqueueMessage和next来插入和读取消息的(注意:消息队列的底层实现是单链表并非队列)
(1) 首先我们来分析一下enqueueMessage的源码实现:
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
…
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 {
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;
}
从源码可以清楚的看见,enqueueMessage就是简单的单链表的插入操作,前面做了一些条件判断和线程锁操作,红色部分就是将消息添加到单链表的简单操作。
(2) 接下来看一下next的源码实现
Message next() {
…
int pendingIdleHandlerCount = -1; // -1 only during first iteration
int nextPollTimeoutMillis = 0;
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis);
synchronized (this) {
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
if (msg != null && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
nextPollTimeoutMillis = (int) Math.min(
msg.when - now, Integer.MAX_VALUE);
} else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
if (DEBUG) Log.v(TAG, "Returning message: " + msg);
msg.markInUse();
return msg;
}
} else {
// No more messages.
nextPollTimeoutMillis = -1;
}
// Process the quit message now that all pending
// messages have been handled.
if (mQuitting) {
dispose();
return null;
}
…
}
…
}
}
从源码很容易就看出来,next内部有一个for(;;)死循环,如果MessageQueue中没有消息,next会循环等待,若有消息,则会将消息返回,并且将消息从MessageQueue中移除。
至此,整个Handler机制的分析就全部结束了,最后,用一张图来总结一下Handler消息的传递顺序及其调用的关系: