當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]? ? Handler和Message是Android開(kāi)發(fā)者常用的兩個(gè)API,我一直對(duì)于它的內(nèi)部實(shí)現(xiàn)比較好奇,所以用空閑的時(shí)間,閱讀了一下他們的源碼。? ?相關(guān)的Java Class: android


? ? 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)的解析。 ? ??

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉