核心代碼在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(阻塞線程)
- 交給與之關(guān)聯(lián)的Handler處理
- 回收Message铅祸,供Message.obtain()復(fù)用
MessageQueen:
說(shuō)明:
MessageQueue中的mMessages保存鏈表的第一個(gè)元素。
循環(huán)體內(nèi)首先調(diào)用nativePollOnce(ptr, nextPollTimeoutMillis)合武,這是一個(gè)native方法临梗,實(shí)際作用就是通過(guò)Native層的MessageQueue阻塞nextPollTimeoutMillis毫秒的時(shí)間。
1.如果nextPollTimeoutMillis=-1眯杏,一直阻塞不會(huì)超時(shí)夜焦。
2.如果nextPollTimeoutMillis=0,不會(huì)阻塞岂贩,立即返回茫经。
3.如果nextPollTimeoutMillis>0,最長(zhǎng)阻塞nextPollTimeoutMillis毫秒(超時(shí))萎津,如果期間有程序喚醒會(huì)立即返回卸伞。
獲取消息:
1.首次進(jìn)入循環(huán)nextPollTimeoutMillis=0,阻塞方法nativePollOnce(ptr, nextPollTimeoutMillis)會(huì)立即返回
2.讀取列表中的消息锉屈,如果發(fā)現(xiàn)消息屏障荤傲,則跳過(guò)后面的同步消息,總之會(huì)通過(guò)當(dāng)前時(shí)間颈渊,是否遇到屏障來(lái)返回符合條件的待處理消息
3.如果沒(méi)有符合條件的消息遂黍,會(huì)處理一些不緊急的任務(wù)(IdleHandler),再次進(jìn)入第一步
加入消息:
1.加入消息比較簡(jiǎn)單俊嗽,按時(shí)間順序插入到消息鏈表中雾家。
a如果是第一個(gè)那么根據(jù)mBlocked判斷是否需要喚醒線程,
b.如果不是第一個(gè)一般情況下不需要喚醒(如果加入的消息是異步的需要另外判斷)