核心代码在MessageQueen
参考:MessageQueen原理
Loop代码:
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
msg.target.dispatchMessage(msg);
msg.recycleUnchecked();
}
- 从MessageQueue中获取待处理的Message(阻塞线程)
- 交给与之关联的Handler处理
- 回收Message,供Message.obtain()复用
MessageQueen:
说明:
MessageQueue中的mMessages保存链表的第一个元素。
循环体内首先调用nativePollOnce(ptr, nextPollTimeoutMillis),这是一个native方法,实际作用就是通过Native层的MessageQueue阻塞nextPollTimeoutMillis毫秒的时间。
1.如果nextPollTimeoutMillis=-1,一直阻塞不会超时。
2.如果nextPollTimeoutMillis=0,不会阻塞,立即返回。
3.如果nextPollTimeoutMillis>0,最长阻塞nextPollTimeoutMillis毫秒(超时),如果期间有程序唤醒会立即返回。
获取消息:
1.首次进入循环nextPollTimeoutMillis=0,阻塞方法nativePollOnce(ptr, nextPollTimeoutMillis)会立即返回
2.读取列表中的消息,如果发现消息屏障,则跳过后面的同步消息,总之会通过当前时间,是否遇到屏障来返回符合条件的待处理消息
3.如果没有符合条件的消息,会处理一些不紧急的任务(IdleHandler),再次进入第一步
加入消息:
1.加入消息比较简单,按时间顺序插入到消息链表中。
a如果是第一个那么根据mBlocked判断是否需要唤醒线程,
b.如果不是第一个一般情况下不需要唤醒(如果加入的消息是异步的需要另外判断)
网友评论