Android消息機(jī)制不完全解析(上)
? ? Handler和Message是Android開(kāi)發(fā)者常用的兩個(gè)API,我一直對(duì)于它的內(nèi)部實(shí)現(xiàn)比較好奇,所以用空閑的時(shí)間,閱讀了一下他們的源碼。
? ?相關(guān)的Java Class:
android.os.Messageandroid.os.MessageQueueandroid.os.Looperandroid.os.Handler
? ? 相關(guān)的C++ Class:
android.NativeMessageQueueandroid.Looperandroid.LooperCallbackandroid.SimpleLooperCallbackandroid.Messageandroid.MessageHandler
首先,來(lái)看看這些類之間的關(guān)系:
首先,讓我們從相對(duì)簡(jiǎn)單的java實(shí)現(xiàn)開(kāi)始看起:
Message ? ? Message類可以說(shuō)是最簡(jiǎn)單的,主要提供了一些成員,用以保存消息數(shù)據(jù)。
????public?int?what;//用以表示消息類別 ????public?int?arg1;//消息數(shù)據(jù) ????public?int?arg2;//消息數(shù)據(jù) ????public?Object?obj;//消息數(shù)據(jù)
????/*package*/?long?when;//消息應(yīng)該被處理的時(shí)間 ???? ????/*package*/?Bundle?data;//消息數(shù)據(jù) ???? ????/*package*/?Handler?target;//處理這個(gè)消息的handler ???? ????/*package*/?Runnable?callback;//回調(diào)函數(shù) ???? ????//?sometimes?we?store?linked?lists?of?these?things ????/*package*/?Message?next;//形成鏈表,保存Message實(shí)例
? ? 值得一提的是,Android提供了一個(gè)簡(jiǎn)單,但是有用的消息池,對(duì)于Message這種使用頻繁的類型,可以有效的減少內(nèi)存申請(qǐng)和釋放的次數(shù),提高性能。
????private?static?final?Object?sPoolSync?=?new?Object(); ????private?static?Message?sPool; ????private?static?int?sPoolSize?=?0; ????private?static?final?int?MAX_POOL_SIZE?=?50;
????/** ?????*?Return?a?new?Message?instance?from?the?global?pool.?Allows?us?to ?????*?avoid?allocating?new?objects?in?many?cases. ?????*/ ????public?static?Message?obtain()?{ ????????synchronized?(sPoolSync)?{ ????????????if?(sPool?!=?null)?{//消息池不為空,則從消息池中獲取實(shí)例 ????????????????Message?m?=?sPool; ????????????????sPool?=?m.next; ????????????????m.next?=?null; ????????????????sPoolSize--; ????????????????return?m; ????????????} ????????} ????????return?new?Message(); ????} ????/** ?????*?Return?a?Message?instance?to?the?global?pool.??You?MUST?NOT?touch ?????*?the?Message?after?calling?this?function?--?it?has?effectively?been ?????*?freed. ?????*/ ????public?void?recycle()?{ ????????clearForRecycle(); ????????synchronized?(sPoolSync)?{ ????????????if?(sPoolSize?<?MAX_POOL_SIZE)?{//消息池大小未滿,則放入消息池 ????????????????next?=?sPool; ????????????????sPool?=?this; ????????????????sPoolSize++; ????????????} ????????} ????} ????/*package*/?void?clearForRecycle()?{ ????????flags?=?0; ????????what?=?0; ????????arg1?=?0; ????????arg2?=?0; ????????obj?=?null; ????????replyTo?=?null; ????????when?=?0; ????????target?=?null; ????????callback?=?null; ????????data?=?null; ????}
? ? 小結(jié):
Message的核心在于它的數(shù)據(jù)域,Handler根據(jù)這些內(nèi)容來(lái)識(shí)別和處理消息應(yīng)該使用Message.obtain(或者Handler.obtainMessage)函數(shù)獲取message實(shí)例
Handler
? ? 首先看看構(gòu)造函數(shù):
????public?interface?Callback?{ ????????public?boolean?handleMessage(Message?msg); ????}
????public?Handler()?{ ????????this(null,?false); ????}
????public?Handler(Callback?callback,?boolean?async)?{ ????????if?(FIND_POTENTIAL_LEAKS)?{ ????????????final?Class?klass?=?getClass(); ????????????if?((klass.isAnonymousClass()?||?klass.isMemberClass()?||?klass.isLocalClass())?&& ????????????????????(klass.getModifiers()?&?Modifier.STATIC)?==?0)?{ ????????????????Log.w(TAG,?"The?following?Handler?class?should?be?static?or?leaks?might?occur:?"?+ ????????????????????klass.getCanonicalName()); ????????????} ????????} ????????mLooper?=?Looper.myLooper(); ????????if?(mLooper?==?null)?{ ????????????throw?new?RuntimeException( ????????????????"Can't?create?handler?inside?thread?that?has?not?called?Looper.prepare()"); ????????} ????????mQueue?=?mLooper.mQueue; ????????mCallback?=?callback;?//使用Callback可以攔截Handler處理消息,之后會(huì)在dispatchMessage函數(shù)中,大展身手 ????????mAsynchronous?=?async;//設(shè)置handler的消息為異步消息,暫時(shí)先無(wú)視這個(gè)變量 ????}
? ? Handler的構(gòu)造函數(shù)最主要的就是初始化成員變量:mLooper和mQueue。 這邊需要注意的一個(gè)問(wèn)題是:Looper.myLooper()不能返回null,否則拋出RuntimeExeception。稍后詳解Looper.myLooper();函數(shù)在何種情況下會(huì)拋出異常。
? ? Handler.obtainMessage系列的函數(shù)都會(huì)調(diào)用Message類中對(duì)應(yīng)的靜態(tài)方法,從消息池中獲取一個(gè)可用的消息實(shí)例。典型實(shí)現(xiàn)如下:
????public?final?Message?obtainMessage() ????{ ????????return?Message.obtain(this); ????}
? ? Handler.post系列和send系列函數(shù)最終都會(huì)調(diào)用enqueueMessage函數(shù),把message入列,不同之處在于post系列函數(shù)會(huì)以Runable參數(shù)構(gòu)建一個(gè)Message實(shí)例。
?????private?static?Message?getPostMessage(Runnable?r)?{ ????????Message?m?=?Message.obtain(); ????????m.callback?=?r;//一會(huì)我們會(huì)看到callback非空的message和callback為空的mesage在處理時(shí)的差異 ????????return?m; ????} ????public?final?boolean?post(Runnable?r) ????{ ???????return??sendMessageDelayed(getPostMessage(r),?0); ????} ????public?final?boolean?sendMessage(Message?msg) ????{ ????????return?sendMessageDelayed(msg,?0); ????} ????public?final?boolean?sendMessageDelayed(Message?msg,?long?delayMillis) ????{ ????????if?(delayMillis?<?0)?{ ????????????delayMillis?=?0; ????????} ????????return?sendMessageAtTime(msg,?SystemClock.uptimeMillis()?+?delayMillis); ????} ????public?boolean?sendMessageAtTime(Message?msg,?long?uptimeMillis)?{ ????????MessageQueue?queue?=?mQueue; ????????if?(queue?==?null)?{ ????????????RuntimeException?e?=?new?RuntimeException( ????????????????????this?+?"?sendMessageAtTime()?called?with?no?mQueue"); ????????????Log.w("Looper",?e.getMessage(),?e); ????????????return?false; ????????} ????????return?enqueueMessage(queue,?msg,?uptimeMillis); ????} ????//最終都會(huì)調(diào)用這個(gè)函數(shù),把message入列 ????private?boolean?enqueueMessage(MessageQueue?queue,?Message?msg,?long?uptimeMillis)?{ ????????msg.target?=?this; ????????if?(mAsynchronous)?{ ????????????msg.setAsynchronous(true);//Handler的mAsynchronous屬性,決定了msg是否為asynchronous,稍后在MessageQueue.next函數(shù)中,可以看到asynchronous對(duì)于消息處理的影響 ????????} ????????return?queue.enqueueMessage(msg,?uptimeMillis); ????}
? ? 除了這些之外,Handler還提供了hasMessage系列和removeMessages系列函數(shù)用以管理Handler對(duì)應(yīng)的MessageQueue中的消息。
? ? 接下來(lái)主角登場(chǎng),Handler.dispatchMessage:
????private?static?void?handleCallback(Message?message)?{ ????????message.callback.run(); ????} ????/** ?????*?Subclasses?must?implement?this?to?receive?messages. ?????*/ ????public?void?handleMessage(Message?msg)?{ ????} ???? ????/** ?????*?Handle?system?messages?here. ?????*/ ????public?void?dispatchMessage(Message?msg)?{ ????????if?(msg.callback?!=?null)?{//message的callback不為null,則執(zhí)行 ????????????handleCallback(msg); ????????}?else?{ ????????????if?(mCallback?!=?null)?{//如果Hanlder的mCallback成員不為null,則調(diào)用 ????????????????if?(mCallback.handleMessage(msg))?{//如果handleMessage返回值為true,則攔截消息 ????????????????????return; ????????????????} ????????????} ????????????handleMessage(msg);//處理消息 ????????} ????}
? ? 注釋應(yīng)該比較清楚,不多說(shuō)。 小結(jié):
?Handler類最為核心的函數(shù)是enqueueMessage和dispatcherMessage,前者把待處理的消息放入MessageQueue,而Looper調(diào)用后者來(lái)處理從MessageQueue獲取的消息。?callback不為null(通過(guò)post系列函數(shù)添加到消息隊(duì)列中)的message無(wú)法被攔截,而callback為null的函數(shù)可以被Handler的mCallback攔截
Looper ? ? 同樣從構(gòu)造函數(shù)看起:
????private?Looper(boolean?quitAllowed)?{ ????????mQueue?=?new?MessageQueue(quitAllowed);//每個(gè)Looper有一個(gè)MessageQueue ????????mRun?=?true; ????????mThread?=?Thread.currentThread(); ????}
?????**?Initialize?the?current?thread?as?a?looper. ??????*?This?gives?you?a?chance?to?create?handlers?that?then?reference ??????*?this?looper,?before?actually?starting?the?loop.?Be?sure?to?call ??????*?{@link?#loop()}?after?calling?this?method,?and?end?it?by?calling ??????*?{@link?#quit()}. ??????*/ ????public?static?void?prepare()?{ ????????prepare(true);//后臺(tái)線程的looper都允許退出 ????} ????private?static?void?prepare(boolean?quitAllowed)?{ ????????if?(sThreadLocal.get()?!=?null)?{ ????????????throw?new?RuntimeException("Only?one?Looper?may?be?created?per?thread");//每個(gè)線程只能有一個(gè)Looper ????????} ????????sThreadLocal.set(new?Looper(quitAllowed));//把實(shí)例保存到TLS(Thread?Local?Save),僅有每個(gè)線程訪問(wèn)自己的Looper ????} ????/** ?????*?Initialize?the?current?thread?as?a?looper,?marking?it?as?an ?????*?application's?main?looper.?The?main?looper?for?your?application ?????*?is?created?by?the?Android?environment,?so?you?should?never?need ?????*?to?call?this?function?yourself.??See?also:?{@link?#prepare()} ?????*/ ????public?static?void?prepareMainLooper()?{ ????????prepare(false);//主線程的lopper不可以退出 ????????synchronized?(Looper.class)?{ ????????????if?(sMainLooper?!=?null)?{ ????????????????throw?new?IllegalStateException("The?main?Looper?has?already?been?prepared."); ????????????} ????????????sMainLooper?=?myLooper(); ????????} ????}
? ? 因?yàn)槭撬接械臉?gòu)造函數(shù),所以理論上來(lái)說(shuō)只能通過(guò)prepare和prepareMainLooper兩個(gè)函數(shù)來(lái)實(shí)例化Looper,但是google的注釋也說(shuō)的很清楚:prepareMainLooper()應(yīng)該由系統(tǒng)調(diào)用(有興趣的同學(xué)可以去看看AtivityThread類的main函數(shù)),所以,應(yīng)用開(kāi)發(fā)者可以使用的只剩下prepare函數(shù)。
? ? 好了,Looper的實(shí)例是構(gòu)造出來(lái),但是如何獲取構(gòu)造出來(lái)的實(shí)例呢?
????/**?Returns?the?application's?main?looper,?which?lives?in?the?main?thread?of?the?application. ?????*/ ????public?static?Looper?getMainLooper()?{ ????????synchronized?(Looper.class)?{ ????????????return?sMainLooper; ????????} ????} ????/** ?????*?Return?the?Looper?object?associated?with?the?current?thread.??Returns ?????*?null?if?the?calling?thread?is?not?associated?with?a?Looper. ?????*/ ????public?static?Looper?myLooper()?{ ????????return?sThreadLocal.get(); ????}
? ? ?現(xiàn)在,我們應(yīng)該知道如何防止Handler實(shí)例化的時(shí)候,拋出RuntimeException:在守護(hù)線程中實(shí)例化Handler之前,需要先調(diào)用Looper.perpare函數(shù)來(lái)構(gòu)造Looper實(shí)例。
? ? ?然后,重頭戲來(lái)了:?
????/** ?????*?Quits?the?looper. ?????* ?????*?Causes?the?{@link?#loop}?method?to?terminate?as?soon?as?possible. ?????*/ ????public?void?quit()?{ ????????mQueue.quit(); ????} ????/** ?????*?Run?the?message?queue?in?this?thread.?Be?sure?to?call ?????*?{@link?#quit()}?to?end?the?loop. ?????*/ ????public?static?void?loop()?{ ????????final?Looper?me?=?myLooper(); ????????if?(me?==?null)?{//調(diào)用looper之前,需要先調(diào)用perpare,否則您懂的... ????????????throw?new?RuntimeException("No?Looper;?Looper.prepare()?wasn't?called?on?this?thread."); ????????} ????????final?MessageQueue?queue?=?me.mQueue; ????????//?Make?sure?the?identity?of?this?thread?is?that?of?the?local?process, ????????//?and?keep?track?of?what?that?identity?token?actually?is. ????????Binder.clearCallingIdentity();//不太明白這個(gè)函數(shù),但不是重點(diǎn)可以無(wú)視 ????????final?long?ident?=?Binder.clearCallingIdentity(); ????????for?(;;)?{ ????????????Message?msg?=?queue.next();?//?might?block?獲取一個(gè)下一個(gè)消息,如果當(dāng)前沒(méi)有要處理的消息,則block,之后我們會(huì)看到這個(gè)API的實(shí)現(xiàn) ????????????if?(msg?==?null)?{//調(diào)用了MessgeQueu的quit函數(shù)后,MessageQueue.next會(huì)返回null ????????????????//?No?message?indicates?that?the?message?queue?is?quitting. ????????????????return; ????????????} ????????????//?This?must?be?in?a?local?variable,?in?case?a?UI?event?sets?the?logger ????????????Printer?logging?=?me.mLogging; ????????????if?(logging?!=?null)?{//借助logging我們可以打印Looper中處理的消息 ????????????????logging.println(">>>>>?Dispatching?to?"?+?msg.target?+?"?"?+ ????????????????????????msg.callback?+?":?"?+?msg.what); ????????????} ????????????msg.target.dispatchMessage(msg);//調(diào)用handler處理消息 ????????????if?(logging?!=?null)?{ ????????????????logging.println("<<<<<?Finished?to?"?+?msg.target?+?"?"?+?msg.callback); ????????????} ????????????//?Make?sure?that?during?the?course?of?dispatching?the ????????????//?identity?of?the?thread?wasn't?corrupted. ????????????final?long?newIdent?=?Binder.clearCallingIdentity();//選擇性無(wú)視 ????????????if?(ident?!=?newIdent)?{ ????????????????Log.wtf(TAG,?"Thread?identity?changed?from?0x" ????????????????????????+?Long.toHexString(ident)?+?"?to?0x" ????????????????????????+?Long.toHexString(newIdent)?+?"?while?dispatching?to?" ????????????????????????+?msg.target.getClass().getName()?+?"?" ????????????????????????+?msg.callback?+?"?what="?+?msg.what); ????????????} ????????????msg.recycle();//回收消息到消息池 ????????} ????}
? ? Looper.loop()函數(shù)是Looper類的核心函數(shù),主要循環(huán)進(jìn)行兩個(gè)操作:
從MessageQueue中獲取一個(gè)消息,當(dāng)前沒(méi)有消息需要處理時(shí),則block調(diào)用message的Handler(target)處理消息
? ? 基本上,我們可以把Looper理解為一個(gè)死循環(huán),Looper開(kāi)始work以后,線程就進(jìn)入了以消息為驅(qū)動(dòng)的工作模型。
? ? 小結(jié):
每個(gè)線程最多可以有一個(gè)Looper。每個(gè)Looper有且僅有一個(gè)MessageQueue每個(gè)Handler關(guān)聯(lián)一個(gè)MessageQueue,由該MessageQueue關(guān)聯(lián)的Looper執(zhí)行(調(diào)用Hanlder.dispatchMessage)每個(gè)MessageQueue可以關(guān)聯(lián)任意多個(gè)HandlerLooper API的調(diào)用順序:Looper.prepare >> Looper.loop >> Looper.quitLooper的核心函數(shù)是Looper.loop,一般loop不會(huì)返回,直到線程退出,所以需要線程完成某個(gè)work時(shí),請(qǐng)發(fā)送消息給Message(或者說(shuō)Handler)
MessageQueue
? ??
? ? MessageQueue類是唯一包含native函數(shù)的類,我們先大致看一下,稍后C++的部分在詳細(xì)解釋:
????private?native?void?nativeInit();????//初始化 ????private?native?void?nativeDestroy();?//銷毀 ????private?native?void?nativePollOnce(int?ptr,?int?timeoutMillis);?//等待timeoutMillis指定的時(shí)間 ????private?native?void?nativeWake(int?ptr);//喚醒nativePollOnce的等待
? ? 然后,我們?cè)購(gòu)臉?gòu)造函數(shù)看起:
???? ????Message?mMessages;//數(shù)據(jù)域mMessages的類型雖然是Message,但是因?yàn)镸essage.next數(shù)據(jù)域的原因,其實(shí)mMessage是鏈表的第一個(gè)元素 ????MessageQueue(boolean?quitAllowed)?{ ????????mQuitAllowed?=?quitAllowed; ????????nativeInit();//初始化nativeMessageQueue ????}
? ? 對(duì)應(yīng)的,在銷毀的時(shí)候:
????@Override ????protected?void?finalize()?throws?Throwable?{ ????????try?{ ????????????nativeDestroy();//銷毀nativeMessageQueue ????????}?finally?{ ????????????super.finalize(); ????????} ????}
? ??
? ? 此外,MessageQueue提供了一組函數(shù)(e.g. hasMessage, removeMessage)來(lái)查詢和移除待處理的消息,我們?cè)谇懊娴腍andler類上看到的對(duì)應(yīng)函數(shù)的實(shí)現(xiàn)就是調(diào)用這組函數(shù)。
? ? 接下來(lái),看看enqueueMessage函數(shù),Handler函數(shù)就是調(diào)用這個(gè)函數(shù)把message放到MessageQueue中:
????final?boolean?enqueueMessage(Message?msg,?long?when)?{ ????????if?(msg.isInUse())?{//檢查msg是否在使用中,一會(huì)我們可以看到MessageQueue.next()在返回前通過(guò)Message.makeInUse函數(shù)設(shè)置msg為使用狀態(tài),而我們之前看到過(guò)Looper.loop中通過(guò)調(diào)用調(diào)用Message.recycle(),把Message重置為未使用的狀態(tài)。 ????????????throw?new?AndroidRuntimeException(msg?+?"?This?message?is?already?in?use."); ????????} ????????if?(msg.target?==?null)?{//msg必須知道由那個(gè)Handler負(fù)責(zé)處理它 ????????????throw?new?AndroidRuntimeException("Message?must?have?a?target."); ????????} ????????boolean?needWake; ????????synchronized?(this)?{ ????????????if?(mQuiting)?{//如果已經(jīng)調(diào)用MessageQueue.quit,那么不再接收新的Message ????????????????RuntimeException?e?=?new?RuntimeException( ????????????????????????msg.target?+?"?sending?message?to?a?Handler?on?a?dead?thread"); ????????????????Log.w("MessageQueue",?e.getMessage(),?e); ????????????????return?false; ????????????} ????????????msg.when?=?when; ????????????Message?p?=?mMessages; ????????????if?(p?==?null?||?when?==?0?||?when?<?p.when)?{//插到列表頭 ????????????????//?New?head,?wake?up?the?event?queue?if?blocked. ????????????????msg.next?=?p; ????????????????mMessages?=?msg; ????????????????needWake?=?mBlocked;//當(dāng)前MessageQueue處于block狀態(tài),所以需要喚醒 ????????????}?else?{ ????????????????//?Inserted?within?the?middle?of?the?queue.??Usually?we?don't?have?to?wake ????????????????//?up?the?event?queue?unless?there?is?a?barrier?at?the?head?of?the?queue ????????????????//?and?the?message?is?the?earliest?asynchronous?message?in?the?queue. ????????????????needWake?=?mBlocked?&&?p.target?==?null?&&?msg.isAsynchronous();//當(dāng)且僅當(dāng)MessageQueue因?yàn)镾ync?Barrier而block,并且msg為異步消息時(shí),喚醒。?關(guān)于msg.isAsyncChronous(),請(qǐng)回去看看Handler.enqueueMessage函數(shù)和構(gòu)造函數(shù) ????????????????Message?prev; ????????????????for?(;;)?{//?根據(jù)when的大小順序,插入到合適的位置 ????????????????????prev?=?p; ????????????????????p?=?p.next; ????????????????????if?(p?==?null?||?when?<?p.when)?{ ????????????????????????break; ????????????????????} ????????????????????if?(needWake?&&?p.isAsynchronous())?{//如果在插入位置以前,發(fā)現(xiàn)異步消息,則不需要喚醒 ????????????????????????needWake?=?false; ????????????????????} ????????????????} ????????????????msg.next?=?p;?//?invariant:?p?==?prev.next ????????????????prev.next?=?msg; ????????????} ????????} ????????if?(needWake)?{ ????????????nativeWake(mPtr);//喚醒nativeMessageQueue ????????} ????????return?true; ????} ? ????final?void?quit()?{ ????????if?(!mQuitAllowed)?{//UI線程的Looper消息隊(duì)列不可退出 ????????????throw?new?RuntimeException("Main?thread?not?allowed?to?quit."); ????????} ????????synchronized?(this)?{ ????????????if?(mQuiting)?{ ????????????????return; ????????????} ????????????mQuiting?=?true; ????????} ????????nativeWake(mPtr);//喚醒nativeMessageQueue ????}
? ? 關(guān)于sync barrier,再補(bǔ)充點(diǎn)解釋: sync barrier是起到了一個(gè)阻塞器的作用,它可以阻塞when>它(即執(zhí)行時(shí)間比它晚)的同步消息的執(zhí)行,但不影響異步消息。sync barrier的特征是targe為null,所以它只能被remove,無(wú)法被執(zhí)行。MessageQueue提供了下面兩個(gè)函數(shù)來(lái)控制MessageQueue中的sync barrier(如何覺(jué)得sync barrier和異步消息難以理解的話,選擇性無(wú)視就好,因?yàn)樗鼈儾环恋K我們理解Android消息機(jī)制的原理):
????final?int?enqueueSyncBarrier(long?when)?{ ????????//?Enqueue?a?new?sync?barrier?token. ????????//?We?don't?need?to?wake?the?queue?because?the?purpose?of?a?barrier?is?to?stall?it. ????????synchronized?(this)?{ ????????????final?int?token?=?mNextBarrierToken++; ????????????final?Message?msg?=?Message.obtain(); ????????????msg.arg1?=?token; ????????????Message?prev?=?null; ????????????Message?p?=?mMessages; ????????????if?(when?!=?0)?{ ????????????????while?(p?!=?null?&&?p.when?<=?when)?{ ????????????????????prev?=?p; ????????????????????p?=?p.next; ????????????????} ????????????} ????????????if?(prev?!=?null)?{?//?invariant:?p?==?prev.next ????????????????msg.next?=?p; ????????????????prev.next?=?msg; ????????????}?else?{ ????????????????msg.next?=?p; ????????????????mMessages?=?msg; ????????????} ????????????return?token; ????????} ????} ????final?void?removeSyncBarrier(int?token)?{ ????????//?Remove?a?sync?barrier?token?from?the?queue. ????????//?If?the?queue?is?no?longer?stalled?by?a?barrier?then?wake?it. ????????final?boolean?needWake; ????????synchronized?(this)?{ ????????????Message?prev?=?null; ????????????Message?p?=?mMessages; ????????????while?(p?!=?null?&&?(p.target?!=?null?||?p.arg1?!=?token))?{ ????????????????prev?=?p; ????????????????p?=?p.next; ????????????} ????????????if?(p?==?null)?{ ????????????????throw?new?IllegalStateException("The?specified?message?queue?synchronization?" ????????????????????????+?"?barrier?token?has?not?been?posted?or?has?already?been?removed."); ????????????} ????????????if?(prev?!=?null)?{ ????????????????prev.next?=?p.next; ????????????????needWake?=?false; ????????????}?else?{ ????????????????mMessages?=?p.next; ????????????????needWake?=?mMessages?==?null?||?mMessages.target?!=?null;//其實(shí)我覺(jué)得這邊應(yīng)該是needWake?=?mMessages?!=?null?&&?mMessages.target?!=?null ????????????} ????????????p.recycle(); ????????} ????????if?(needWake)?{ ????????????nativeWake(mPtr);//有需要的話,喚醒nativeMessageQueue ????????} ????}
? ? 重頭戲又來(lái)了:
??final?Message?next()?{ ????????int?pendingIdleHandlerCount?=?-1;?//?-1?only?during?first?iteration ????????int?nextPollTimeoutMillis?=?0; ????????for?(;;)?{ ????????????if?(nextPollTimeoutMillis?!=?0)?{ ????????????????Binder.flushPendingCommands();//不太理解,選擇性無(wú)視 ????????????} ????????????nativePollOnce(mPtr,?nextPollTimeoutMillis);//等待nativeMessageQueue返回,最多等待nextPollTimeoutMillis毫秒 ????????????synchronized?(this)?{ ????????????????if?(mQuiting)?{//如果要退出,則返回null ????????????????????return?null; ????????????????} ????????????????//?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)?{//下一個(gè)消息為sync?barrier ????????????????????//?Stalled?by?a?barrier.??Find?the?next?asynchronous?message?in?the?queue. ????????????????????do?{ ????????????????????????prevMsg?=?msg; ????????????????????????msg?=?msg.next; ????????????????????}?while?(msg?!=?null?&&?!msg.isAsynchronous());//因?yàn)榇嬖趕ync?barrier,僅有異步消息可以執(zhí)行,所以尋在最近的異步消息 ????????????????} ????????????????if?(msg?!=?null)?{ ????????????????????if?(now?<?msg.when)?{ ????????????????????????//?Next?message?is?not?ready.??Set?a?timeout?to?wake?up?when?it?is?ready. ????????????????????????nextPollTimeoutMillis?=?(int)?Math.min(msg.when?-?now,?Integer.MAX_VALUE);//消息還沒(méi)到執(zhí)行的時(shí)間,所以我們繼續(xù)等待msg.when?-?now毫秒 ????????????????????}?else?{ ????????????????????????//?Got?a?message. ????????????????????????mBlocked?=?false;//開(kāi)始處理消息了,所以不再是blocked狀態(tài) ????????????????????????if?(prevMsg?!=?null)?{ ????????????????????????????prevMsg.next?=?msg.next;//從鏈表中間移除message ????????????????????????}?else?{ ????????????????????????????mMessages?=?msg.next;//從鏈表頭移除message ????????????????????????} ????????????????????????msg.next?=?null; ????????????????????????if?(false)?Log.v("MessageQueue",?"Returning?message:?"?+?msg); ????????????????????????msg.markInUse();//標(biāo)記msg正在使用 ????????????????????????return?msg;//返回到Looper.loop函數(shù) ????????????????????} ????????????????}?else?{ ????????????????????//?No?more?messages. ????????????????????nextPollTimeoutMillis?=?-1;//沒(méi)有消息可以處理,所以無(wú)限制的等待 ????????????????} ????????????????//?If?first?time?idle,?then?get?the?number?of?idlers?to?run. ????????????????//?Idle?handles?only?run?if?the?queue?is?empty?or?if?the?first?message ????????????????//?in?the?queue?(possibly?a?barrier)?is?due?to?be?handled?in?the?future. ????????????????if?(pendingIdleHandlerCount?<?0 ????????????????????????&&?(mMessages?==?null?||?now?<?mMessages.when))?{//?目前無(wú)消息可以處理,可以執(zhí)行IdleHandler ????????????????????pendingIdleHandlerCount?=?mIdleHandlers.size(); ????????????????} ????????????????if?(pendingIdleHandlerCount?<=?0)?{ ????????????????????//?No?idle?handlers?to?run.??Loop?and?wait?some?more. ????????????????????mBlocked?=?true; ????????????????????continue; ????????????????} ????????????????if?(mPendingIdleHandlers?==?null)?{ ????????????????????mPendingIdleHandlers?=?new?IdleHandler[Math.max(pendingIdleHandlerCount,?4)]; ????????????????} ????????????????mPendingIdleHandlers?=?mIdleHandlers.toArray(mPendingIdleHandlers); ????????????} ????????????//?Run?the?idle?handlers. ????????????//?We?only?ever?reach?this?code?block?during?the?first?iteration. ????????????for?(int?i?=?0;?i?<?pendingIdleHandlerCount;?i++)?{ ????????????????final?IdleHandler?idler?=?mPendingIdleHandlers[i]; ????????????????mPendingIdleHandlers[i]?=?null;?//?release?the?reference?to?the?handler ????????????????boolean?keep?=?false; ????????????????try?{ ????????????????????keep?=?idler.queueIdle(); ????????????????}?catch?(Throwable?t)?{ ????????????????????Log.wtf("MessageQueue",?"IdleHandler?threw?exception",?t); ????????????????} ????????????????if?(!keep)?{ ????????????????????synchronized?(this)?{ ????????????????????????mIdleHandlers.remove(idler); ????????????????????} ????????????????} ????????????} ????????????//?Reset?the?idle?handler?count?to?0?so?we?do?not?run?them?again. ????????????pendingIdleHandlerCount?=?0;//Looper.looper調(diào)用一次MessageQueue.next(),只允許調(diào)用一輪IdleHandler ????????????//?While?calling?an?idle?handler,?a?new?message?could?have?been?delivered ????????????//?so?go?back?and?look?again?for?a?pending?message?without?waiting. ????????????nextPollTimeoutMillis?=?0;//因?yàn)閳?zhí)行IdleHandler的過(guò)程中,可能有新的消息到來(lái),所以把等待時(shí)間設(shè)置為0 ????????} ????}
? ? ? ? ? ? ? 為了方便大家理解Message的工作原理,先簡(jiǎn)單描述nativeWake,和natePollonce的作用:
nativePollOnce(mPtr, nextPollTimeoutMillis);暫時(shí)無(wú)視mPtr參數(shù),阻塞等待nextPollTimeoutMillis毫秒的時(shí)間返回,與Object.wait(long timeout)相似nativeWake(mPtr);暫時(shí)無(wú)視mPtr參數(shù),喚醒等待的nativePollOnce函數(shù)返回的線程,從這個(gè)角度解釋nativePollOnce函數(shù)應(yīng)該是最多等待nextPollTimeoutMillis毫秒
? ? 小結(jié):
MessageQueue作為一個(gè)容器,保存了所有待執(zhí)行的消息。MessageQueue中的Message包含三種類型:普通的同步消息,Sync barrier(target = null),異步消息(isAsynchronous() = true)。MessageQueue的核心函數(shù)為enqueueMessage和next,前者用于向容器內(nèi)添加Message,而Looper通過(guò)后者從MessageQueue中獲取消息,并實(shí)現(xiàn)無(wú)消息情況下的等待。MessageQueue把Android消息機(jī)制的Java實(shí)現(xiàn)和C++實(shí)現(xiàn)聯(lián)系起來(lái)。
? ? 本來(lái)我是想一口氣把java實(shí)現(xiàn)和C++實(shí)現(xiàn)都寫完的,但是,無(wú)奈最近工作和個(gè)人事務(wù)都比較多,稍后為大家奉上C++實(shí)現(xiàn)的解析。
? ??