Handler是什么垒探?
Handler在我們android開發(fā)中是一項非常重要的機(jī)制身害,那Handler是什么呢懂讯?Handler是android提供用于更新UI的一套機(jī)制装哆,也是消息處理機(jī)制。
Handler重要的四個類:
? ? ? ? handler (處理器類):用來發(fā)送消息和處理消息旗国。
? ? ? ? looper(循環(huán)類):通過loop(for死循環(huán))查看當(dāng)前的消息鏈表中是否有需要處理的message枯怖。
? ? ? ? messagequeue(消息隊列類):用來存儲message的鏈表(鏈表中的消息message是按when(當(dāng)前系統(tǒng)的時間戳)從小到大的排列)。
? ? ? ? ? message(消息類):用來存儲消息內(nèi)容能曾。
那么如何將這幾個類串聯(lián)起來呢度硝?
通過handler.sendMessage這個方法设捐,把當(dāng)前的消息對象message傳入到handler中,通過handler中的messagequeue對象的引用(通過在handler的構(gòu)造函數(shù)中塘淑,用looper獲取到的)萝招,把Message放入到MessageQueue中。在message存放的時候存捺,message對象的target屬性記錄了當(dāng)前的handler槐沼。message通過消息的執(zhí)行時間when,從小到大排列插入到消息鏈表中捌治。我們looper的loop方法中的for(死循環(huán))去查看當(dāng)前的MessageQueue鏈表中是否有需要執(zhí)行的Message岗钩。通過Message的when(消息的執(zhí)行時間判斷)和當(dāng)前的系統(tǒng)時間戳做對比,如果當(dāng)前的系統(tǒng)時間戳小于當(dāng)前messagequeue鏈表中的消息執(zhí)行時間肖油,當(dāng)前的執(zhí)行進(jìn)入等待狀態(tài)兼吓。(管道機(jī)制,nativepollonce)如果當(dāng)前的系統(tǒng)時間戳大于或等于當(dāng)前的MessageQueue鏈表中的消息執(zhí)行時間森枪,我們就把當(dāng)前的message從消息鏈表中刪除视搏,并且把該消息返回給Looper的loop方法中。在loop方法中獲取到message以后判斷message所對應(yīng)的target(也就是發(fā)送message的handler)是否存在县袱,如果存在就調(diào)用target.dispathMessage方法把當(dāng)前的message傳入浑娜,在dispathMessage方法中,我們將調(diào)用handleMessage這個方法式散。把當(dāng)前取出的message傳出去筋遭。這樣在我們handler中重寫的handleMessage就拿到了當(dāng)前處理的消息。
消息隊列中的消息如何排隊暴拄?
boolean enqueueMessage(Message msg, long when) {
? ? ? ? synchronized (this) {
? ? ? ? ? //將消息執(zhí)行的絕對時間存儲起來
? ? ? ? ? ? msg.when = when;
? ? ? ? ? ? //msg2 : p = msg1
? ? ? ? ? ? //msg3: p? = msg1
? ? ? ? ? ? //msg4: p = msg1
? ? ? ? ? ? //msg5: p = msg4
? ? ? ? ? ? Message p = mMessages;
? ? ? ? ? ? //排序原理:每次新的消息進(jìn)來漓滔,都是和隊首消息比較,
? ? ? ? ? ? //1.如果比隊首執(zhí)行早乖篷,那么當(dāng)前消息到隊首
? ? ? ? ? ? //2.如果比隊首晚响驴,和隊首的下一個(B)比較,如果比B還晚那伐,再和B踏施。next (C) 比較石蔗。罕邀。。养距。
? ? ? ? ? ? if (p == null || when == 0 || when < p.when) {
? ? ? ? ? ? //1.發(fā)現(xiàn)哪個消息可以進(jìn)來诉探??比隊首還要早執(zhí)行的消息棍厌,當(dāng)前消息應(yīng)該是隊首消息肾胯,并且保存成功成員變量
? ? ? ? ? ? ? ? // New head, wake up the event queue if blocked.
? ? ? ? ? ? ? ? //msg1: msg1.next = p = null
? ? ? ? ? ? ? ? //msg4:msg4.next = msg1
? ? ? ? ? ? ? ? msg.next = p;
? ? ? ? ? ? ? ? //msg1:mMessages = msg1
? ? ? ? ? ? ? ? //msg4:mMessages = msg4;
? ? ? ? ? ? ? ? mMessages = msg;
? ? ? ? ? ? } else {
? ? ? ? ? ? //2.能走到這個分支竖席,說明當(dāng)前消息肯定比隊首消息執(zhí)行晚,會從隊首消息的下一個消息開始比較敬肚,直到找到合適的位置位置
? ? ? ? ? ? ? ? Message prev;
? ? ? ? ? ? ? ? for (;;) {
? ? ? ? ? ? ? ? //msg2:prev = p = msg1(1000)(隊首msg)
? ? ? ? ? ? ? ? //msg3:prev = p = msg1(隊首msg)
? ? ? ? ? ? ? ? //msg5:prev = p = msg4(隊首msg)
? ? ? ? ? ? ? ? ? ? prev = p;
? ? ? ? ? ? ? ? ? ? //msg2:p = p.next = msg1.next = null;
? ? ? ? ? ? ? ? ? ? //msg3:p = msg1.next = msg2;
? ? ? ? ? ? ? ? ? ? //msg5: p = p.next = msg1(和隊首消息的下一個消息進(jìn)行比較)
? ? ? ? ? ? ? ? ? ? p = p.next;
? ? ? ? ? ? ? ? ? ? if (p == null || when < p.when) {
? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (needWake && p.isAsynchronous()) {
? ? ? ? ? ? ? ? ? ? ? ? needWake = false;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //msg2:msg2.next = p = null
? ? ? ? ? ? ? ? //msg3: msg3.next = msg2
? ? ? ? ? ? ? ? msg.next = p; // invariant: p == prev.next
? ? ? ? ? ? ? ? //msg2:prev.next = msg1.next = msg = msg2
? ? ? ? ? ? ? ? //msg3:msg1.next = msg3
? ? ? ? ? ? ? ? prev.next = msg;
? ? ? ? ? ? }
? ? ? ? ? ? // We can assume mPtr != 0 because mQuitting is false.
? ? ? ? ? ? if (needWake) {
? ? ? ? ? ? ? ? nativeWake(mPtr);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return true;
? ? }