我所了解的MessageQueue的消息存放過(guò)程
?問(wèn)題
- 對(duì)于Handler,我們?cè)谑煜げ贿^(guò)了,我們經(jīng)常會(huì)這樣 mHandler.sendMessage(msg),也經(jīng)常會(huì)這樣 mHandler.sendEmptyMessageDelayed(0, 1000),但我們知道handler處理消息都是一個(gè)一個(gè)處理的,我們發(fā)送的消息都是會(huì)先存放到消息隊(duì)列中,但這個(gè)消息隊(duì)列是怎么實(shí)現(xiàn)的呢?
?個(gè)人理解
- 之前一直以為這個(gè)隊(duì)列的算法會(huì)很難,但最近看了源碼后,核心代碼不超過(guò)20行(好屌),這個(gè)隊(duì)列的核心思想是每個(gè)Message之間手拉手,就是每個(gè)Message只要知道自己的前面一個(gè)Message和后面一個(gè)Message就可以了,Message之間的排序通過(guò)用時(shí)間戳來(lái)排序,時(shí)間戳小的排在前面。
- 再配合上handler對(duì)于消息的取出,第一個(gè)Message的時(shí)間到了,就取隊(duì)列的第一個(gè)Message,取完之后,將第一個(gè)Message置為空,這樣第二個(gè)Message就排在第一個(gè)了,以此類推。
?代碼實(shí)現(xiàn)
//消息的存放
boolean enqueueMessage(Message msg, long when) {
??? synchronized (this) {
??? msg.when = when;
??? Message p = mMessages;? //注解1
??? if (p == null || when == 0 || when < p.when) {
???????? msg.next = p;
???????? mMessages = msg;? ? //注解2
???? } else {
????????? Message prev;
????????? for (;;) { //注解3
????????????? prev = p;
????????????? p = p.next;
?????????????? if (p == null || when < p.when) {
??????????????? ? ? break;
?????????????? }
????????? }
??? ??? msg.next = p;
??????? prev.next = msg;
?????????? }
??? }
??? return true;
}
- 注解1、2: 沒(méi)有消息時(shí)mMessages為null,如果為null,就將當(dāng)前發(fā)生的msg賦給mMessages,而此時(shí)的msg.next就為null,如果mMessages不為null,說(shuō)明之前已經(jīng)向隊(duì)列中已經(jīng)有Message了,就想前面分析,這時(shí)會(huì)根據(jù)時(shí)間戳來(lái)排序,看誰(shuí)排在最前面,如果新增的msg(msg.when < p.when),那么新增的msg將會(huì)排在最前面,msg的下一個(gè)message將指向mMessages(msg.next = p; mMessages = msg;)。
- 注解3:如果新增進(jìn)來(lái)的msg的時(shí)間戳大于排隊(duì)列中的第一個(gè)message,也就是mMessages,這時(shí)msg就會(huì)進(jìn)行逐個(gè)比較,就是跟消息隊(duì)列的每個(gè)message的時(shí)間戳進(jìn)行比較,找到后就跳出for(;;),然后插入位置(msg.next = p; prev.next = msg;),這里的p為新增的msg時(shí)間戳比p小的那一個(gè)message,prev就是p前面的那個(gè)message。
- 到這里,MessageQueue的消息存放過(guò)程就結(jié)束了。
?結(jié)束語(yǔ)
- 如果能得到你的鼓勵(lì)和指導(dǎo),我可以開(kāi)心一天。