www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

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


? ? Handler和Message是Android開發(fā)者常用的兩個(gè)API,我一直對于它的內(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 首先,來看看這些類之間的關(guān)系:



首先,讓我們從相對簡單的java實(shí)現(xiàn)開始看起:


Message ? ? Message類可以說是最簡單的,主要提供了一些成員,用以保存消息數(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è)簡單,但是有用的消息池,對于Message這種使用頻繁的類型,可以有效的減少內(nèi)存申請和釋放的次數(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)容來識(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í)先無視這個(gè)變量
????}

? ? Handler的構(gòu)造函數(shù)最主要的就是初始化成員變量:mLooper和mQueue。 這邊需要注意的一個(gè)問題是:Looper.myLooper()不能返回null,否則拋出RuntimeExeception。稍后詳解Looper.myLooper();函數(shù)在何種情況下會(huì)拋出異常。


? ? Handler.obtainMessage系列的函數(shù)都會(huì)調(diào)用Message類中對應(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對于消息處理的影響
????????}
????????return?queue.enqueueMessage(msg,?uptimeMillis);
????}

? ? 除了這些之外,Handler還提供了hasMessage系列和removeMessages系列函數(shù)用以管理Handler對應(yīng)的MessageQueue中的消息。



? ? 接下來主角登場,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)該比較清楚,不多說。 小結(jié):

?Handler類最為核心的函數(shù)是enqueueMessage和dispatcherMessage,前者把待處理的消息放入MessageQueue,而Looper調(diào)用后者來處理從MessageQueue獲取的消息。?callback不為null(通過post系列函數(shù)添加到消息隊(duì)列中)的message無法被攔截,而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è)線程訪問自己的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ù),所以理論上來說只能通過prepare和prepareMainLooper兩個(gè)函數(shù)來實(shí)例化Looper,但是google的注釋也說的很清楚:prepareMainLooper()應(yīng)該由系統(tǒng)調(diào)用(有興趣的同學(xué)可以去看看AtivityThread類的main函數(shù)),所以,應(yīng)用開發(fā)者可以使用的只剩下prepare函數(shù)。
? ? 好了,Looper的實(shí)例是構(gòu)造出來,但是如何獲取構(gòu)造出來的實(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ù)來構(gòu)造Looper實(shí)例。
? ? ?然后,重頭戲來了:?

????/**
?????*?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)可以無視
????????final?long?ident?=?Binder.clearCallingIdentity();

????????for?(;;)?{
????????????Message?msg?=?queue.next();?//?might?block?獲取一個(gè)下一個(gè)消息,如果當(dāng)前沒有要處理的消息,則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();//選擇性無視
????????????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)前沒有消息需要處理時(shí),則block調(diào)用message的Handler(target)處理消息 ? ? 基本上,我們可以把Looper理解為一個(gè)死循環(huán),Looper開始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í),請發(fā)送消息給Message(或者說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的等待


? ? 然后,我們再從構(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
????}

? ? 對應(yīng)的,在銷毀的時(shí)候:

????@Override
????protected?void?finalize()?throws?Throwable?{
????????try?{
????????????nativeDestroy();//銷毀nativeMessageQueue
????????}?finally?{
????????????super.finalize();
????????}
????}

? ?? ? ? 此外,MessageQueue提供了一組函數(shù)(e.g. hasMessage, removeMessage)來查詢和移除待處理的消息,我們在前面的Handler類上看到的對應(yīng)函數(shù)的實(shí)現(xiàn)就是調(diào)用這組函數(shù)。
? ? 接下來,看看enqueueMessage函數(shù),Handler函數(shù)就是調(diào)用這個(gè)函數(shù)把message放到MessageQueue中:

????final?boolean?enqueueMessage(Message?msg,?long?when)?{
????????if?(msg.isInUse())?{//檢查msg是否在使用中,一會(huì)我們可以看到MessageQueue.next()在返回前通過Message.makeInUse函數(shù)設(shè)置msg為使用狀態(tài),而我們之前看到過Looper.loop中通過調(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(),請回去看看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,無法被執(zhí)行。MessageQueue提供了下面兩個(gè)函數(shù)來控制MessageQueue中的sync barrier(如何覺得sync barrier和異步消息難以理解的話,選擇性無視就好,因?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í)我覺得這邊應(yīng)該是needWake?=?mMessages?!=?null?&&?mMessages.target?!=?null
????????????}
????????????p.recycle();
????????}
????????if?(needWake)?{
????????????nativeWake(mPtr);//有需要的話,喚醒nativeMessageQueue
????????}
????}


? ? 重頭戲又來了:

??final?Message?next()?{
????????int?pendingIdleHandlerCount?=?-1;?//?-1?only?during?first?iteration
????????int?nextPollTimeoutMillis?=?0;

????????for?(;;)?{
????????????if?(nextPollTimeoutMillis?!=?0)?{
????????????????Binder.flushPendingCommands();//不太理解,選擇性無視
????????????}
????????????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);//消息還沒到執(zhí)行的時(shí)間,所以我們繼續(xù)等待msg.when?-?now毫秒
????????????????????}?else?{
????????????????????????//?Got?a?message.
????????????????????????mBlocked?=?false;//開始處理消息了,所以不再是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;//沒有消息可以處理,所以無限制的等待
????????????????}

????????????????//?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))?{//?目前無消息可以處理,可以執(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的過程中,可能有新的消息到來,所以把等待時(shí)間設(shè)置為0
????????}
????}

? ? ? ? ? ? ? 為了方便大家理解Message的工作原理,先簡單描述nativeWake,和natePollonce的作用: nativePollOnce(mPtr, nextPollTimeoutMillis);暫時(shí)無視mPtr參數(shù),阻塞等待nextPollTimeoutMillis毫秒的時(shí)間返回,與Object.wait(long timeout)相似nativeWake(mPtr);暫時(shí)無視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通過后者從MessageQueue中獲取消息,并實(shí)現(xiàn)無消息情況下的等待。MessageQueue把Android消息機(jī)制的Java實(shí)現(xiàn)和C++實(shí)現(xiàn)聯(lián)系起來。 ? ? 本來我是想一口氣把java實(shí)現(xiàn)和C++實(shí)現(xiàn)都寫完的,但是,無奈最近工作和個(gè)人事務(wù)都比較多,稍后為大家奉上C++實(shí)現(xiàn)的解析。 ? ??

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

其他電腦(比如安卓手機(jī)/平板電腦)的屏幕壞了,你可能想在安排維修之前緊急訪問一些東西。你可以使用android的USB OTG功能(是的,幾乎每個(gè)android都支持這個(gè)功能,你可以將鼠標(biāo)和鍵盤連接到它)。

關(guān)鍵字: USB 鼠標(biāo) Android 樹莓派

Google 宣布與中國 AR 科技公司 XREAL 達(dá)成深度戰(zhàn)略合作,聯(lián)合推出全球首款專為 Android XR 平臺(tái)打造的旗艦級(jí) AR 眼鏡 Project Aura。

關(guān)鍵字: Google XREAL Android XR眼鏡 AR

繼停止維護(hù)AOSP開源項(xiàng)目后,谷歌母公司Alphabet近日被曝在其安卓系統(tǒng)(Android)、Pixel手機(jī)以及Chrome瀏覽器等部門裁員數(shù)百人。這一舉措引發(fā)了業(yè)界的廣泛關(guān)注,也引發(fā)了對谷歌未來業(yè)務(wù)布局的諸多猜測。

關(guān)鍵字: 谷歌 AOSP Android 裁員

在本教程中,我們將使用Capacitor 6、Angular和TypeScript構(gòu)建一個(gè)Android應(yīng)用程序,該應(yīng)用程序通過串行端口連接到BleuIO USB加密狗。該應(yīng)用程序允許用戶直接從Android設(shè)備發(fā)送和接...

關(guān)鍵字: Android USB 電容器 BLE設(shè)備

早前媒體報(bào)道谷歌將停止維護(hù)Android開源項(xiàng)目(AOSP),將Android開發(fā)全面轉(zhuǎn)向內(nèi)部閉源分支,目前這一消息已經(jīng)得到谷歌官方確認(rèn)。

關(guān)鍵字: 谷歌 Android 開源

本項(xiàng)目演示了如何通過OTG (on - go) USB在Android設(shè)備上使用BleuIO USB加密狗作為串行端口。使用電容器6和@adeunis/電容器-串行插件,我們建立串行連接,發(fā)送AT命令,并實(shí)時(shí)讀取響應(yīng)。該...

關(guān)鍵字: 電容器 Android 傳感器 微控制器 嵌入式系統(tǒng)

在Linux操作系統(tǒng)中,Android Debug Bridge(ADB)是一個(gè)功能強(qiáng)大的命令行工具,它允許開發(fā)者在計(jì)算機(jī)和Android設(shè)備之間建立通信,從而進(jìn)行調(diào)試、管理、安裝應(yīng)用等操作。本文將詳細(xì)介紹在Linux系...

關(guān)鍵字: Linux系統(tǒng) Android Debug ADB

隨著Android操作系統(tǒng)的進(jìn)步,智能手機(jī)的使用日益增加。隨后,有報(bào)道稱,惡意個(gè)人和黑客利用 Android 提供的漏洞來訪問用戶珍視的數(shù)據(jù)。例如,此類威脅包括 2021 年針對 Android 設(shè)備發(fā)布的 Flubot...

關(guān)鍵字: Android 惡意軟件

在本教程中,我們將構(gòu)建超出電子領(lǐng)域的東西。作為一名電子工程師,我們大多數(shù)人都想為我們的物聯(lián)網(wǎng)應(yīng)用程序構(gòu)建一些用戶界面,在大多數(shù)情況下,Android應(yīng)用程序?qū)⑹怯脩襞c我們的物聯(lián)網(wǎng)設(shè)備交互的正確選擇。所以,如果你想為你的物...

關(guān)鍵字: 物聯(lián)網(wǎng) Android
關(guān)閉