Android中消息處理機(jī)制研究

消息機(jī)制概述

Android應(yīng)用程序的每一個(gè)線程在啟動(dòng)時(shí),都可以首先在內(nèi)部創(chuàng)建一個(gè)消息隊(duì)列,然后再進(jìn)入一個(gè)無(wú)限循環(huán)中,不斷檢查它的消息隊(duì)列是否有新的消息需要處理,如果有新的消息需要處理,那么線程就會(huì)將它從消息隊(duì)列中取出來(lái),并且對(duì)它進(jìn)行處理;否則線程就會(huì)進(jìn)入睡眠等待狀態(tài),直到有新的消息需要處理為止,這樣就可以通過(guò)消息來(lái)驅(qū)動(dòng)Android應(yīng)用程序的執(zhí)行。

消息機(jī)制組成部分

Android系統(tǒng)主要通過(guò)Messagequeue,Looper,Handler三個(gè)類來(lái)實(shí)現(xiàn)Android應(yīng)用程序的消息處理機(jī)制:

1.Messagequeue:描述消息隊(duì)列

2.Looper:創(chuàng)建消息隊(duì)列,以及進(jìn)入消息循環(huán)

3.Handler:用來(lái)發(fā)送消息和處理消息

消息處理流程

1、程序啟動(dòng)的時(shí)候,主線程會(huì)創(chuàng)建一個(gè)Looper對(duì)象。Looper對(duì)象初始化一個(gè)MessageQueue,然后調(diào)用loop()方法循環(huán)去讀取消息。

2、初始化Handler的時(shí)候,在Handler的構(gòu)造函數(shù)內(nèi)部,會(huì)獲取當(dāng)前線程的Looper對(duì)象,進(jìn)而獲取MessageQueue對(duì)象。由此可見(jiàn),想要操作UI的Handler必須在主線程中創(chuàng)建。否則會(huì)提示你:【”Can’tcreate handler inside thread that has not called Looper.prepare()”】

3、調(diào)用Handler的相關(guān)方法時(shí),會(huì)獲取Message對(duì)象,將消息對(duì)象的target指向當(dāng)前handler對(duì)象,然后放到消息隊(duì)列中。

4、loop()工作中,會(huì)從消息隊(duì)列中獲取一個(gè)個(gè)的消息,調(diào)用handle的dispatchMessage(msg)分發(fā)處理。

5、Message內(nèi)部維護(hù)一個(gè)消息池,用來(lái)回收緩存message對(duì)象。

6、Looper相當(dāng)于一個(gè)發(fā)動(dòng)機(jī),MessageQueue相當(dāng)于流水線,Message相當(dāng)于一個(gè)個(gè)的物品,而Handler就相當(dāng)于工人。

消息循環(huán)機(jī)制機(jī)構(gòu)圖

消息循環(huán)機(jī)制java層與c++層關(guān)系圖

創(chuàng)建線程消息隊(duì)列

1.創(chuàng)建Java層Looper對(duì)象:

[java]view plaincopy

privatestaticvoidprepare(booleanquitAllowed)?{

if(sThreadLocal.get()?!=null)?{

thrownewRuntimeException("Only?one?Looper?may?be?created?per?thread");

}

sThreadLocal.set(newLooper(quitAllowed));//創(chuàng)建looper對(duì)象

}

2.Looper對(duì)象內(nèi)部創(chuàng)建一個(gè)MessageQueue對(duì)象(mQueue):

[java]view plaincopy

privateLooper(booleanquitAllowed)?{

//Looper在創(chuàng)建的時(shí)候會(huì)創(chuàng)建一個(gè)MessageQueue對(duì)象

mQueue?=newMessageQueue(quitAllowed);

mThread?=?Thread.currentThread();

}

3.調(diào)用MessageQueue的nativeInit方法創(chuàng)建一個(gè)NativeMessageQueue對(duì)象:

[java]view plaincopy

MessageQueue(booleanquitAllowed)?{

mQuitAllowed?=?quitAllowed;

mPtr?=?nativeInit();//..

}

4.nativeInit方法返回NativeMessageQueue地址給mPtr:

[cpp]view plaincopy

staticjlong?android_os_MessageQueue_nativeInit(JNIEnv*?env,?jclass?clazz)?{

//在C++層通過(guò)此方法創(chuàng)建一個(gè)NativeMessageQueue對(duì)象

NativeMessageQueue*?nativeMessageQueue?=newNativeMessageQueue();

if(!nativeMessageQueue)?{

jniThrowRuntimeException(env,"Unable?to?allocate?native?queue");

return0;

}

nativeMessageQueue->incStrong(env);

//返回nativeMessageQueue地址給Java層;

returnreinterpret_cast(nativeMessageQueue);

}

5.NativeMessageQueue創(chuàng)建時(shí)內(nèi)部創(chuàng)建一個(gè)C++層Looper(Native)對(duì)象:

[cpp]view plaincopy

NativeMessageQueue::NativeMessageQueue()?:?mPollEnv(NULL),?mPollObj(NULL),?mExceptionObj(NULL)?{

//NativeMessageQueue創(chuàng)建時(shí)會(huì)創(chuàng)建一個(gè)Looper(Native)對(duì)象

mLooper?=?Looper::getForThread();

if(mLooper?==?NULL)?{

mLooper?=newLooper(false);

Looper::setForThread(mLooper);

}

}

6.Looper(Native)創(chuàng)建時(shí)內(nèi)部創(chuàng)建一個(gè)管道通過(guò)兩個(gè)文件描述符管理它:

[cpp]view plaincopy

Looper::Looper(boolallowNonCallbacks)?:?mAllowNonCallbacks(allowNonCallbacks),?mResponseIndex(0)?{

intwakeFds[2];

intresult?=?pipe(wakeFds);//創(chuàng)建一個(gè)管道

LOG_ALWAYS_FATAL_IF(result?!=?0,"Could?not?create?wake?pipe.??errno=%d",?errno);

mWakeReadPipeFd?=?wakeFds[0];//讀端文件描述符

mWakeWritePipeFd?=?wakeFds[1];//寫(xiě)端文件描述符

result?=?fcntl(mWakeReadPipeFd,?F_SETFL,?O_NONBLOCK);

LOG_ALWAYS_FATAL_IF(result?!=?0,"Could?not?make?wake?read?pipe?non-blocking.??errno=%d",errno);

result?=?fcntl(mWakeWritePipeFd,?F_SETFL,?O_NONBLOCK);

LOG_ALWAYS_FATAL_IF(result?!=?0,"Could?not?make?wake?write?pipe?non-blocking.??errno=%d",errno);

#ifdef?LOOPER_USES_EPOLL

//?Allocate?the?epoll?instance?and?register?the?wake?pipe.

mEpollFd?=?epoll_create(EPOLL_SIZE_HINT);//..

LOG_ALWAYS_FATAL_IF(mEpollFd?<?0,"Could?not?create?epoll?instance.??errno=%d",?errno);

structepoll_event?eventItem;

memset(&?eventItem,?0,sizeof(epoll_event));//?zero?out?unused?members?of?data?field?union

eventItem.events?=?EPOLLIN;

eventItem.data.fd?=?mWakeReadPipeFd;

//將文件描述符放在epoll中進(jìn)行管理

result?=?epoll_ctl(mEpollFd,?EPOLL_CTL_ADD,?mWakeReadPipeFd,?&?eventItem);

LOG_ALWAYS_FATAL_IF(result?!=?0,"Could?not?add?wake?read?pipe?to?epoll?instance.??errno=%d",errno);

#else

//?Add?the?wake?pipe?to?the?head?of?the?request?list?with?a?null?callback.

structpollfd?requestedFd;

requestedFd.fd?=?mWakeReadPipeFd;

requestedFd.events?=?POLLIN;

mRequestedFds.push(requestedFd);

Request?request;

request.fd?=?mWakeReadPipeFd;

request.callback?=?NULL;

request.ident?=?0;

request.data?=?NULL;

mRequests.push(request);

mPolling?=false;

mWaiters?=?0;

#endif

#ifdef?LOOPER_STATISTICS

mPendingWakeTime?=?-1;

mPendingWakeCount?=?0;

mSampledWakeCycles?=?0;

mSampledWakeCountSum?=?0;

mSampledWakeLatencySum?=?0;

mSampledPolls?=?0;

mSampledZeroPollCount?=?0;

mSampledZeroPollLatencySum?=?0;

mSampledTimeoutPollCount?=?0;

mSampledTimeoutPollLatencySum?=?0;

#endif

}

消息循環(huán)過(guò)程

1.Looper獲取當(dāng)前線程MessageQueue并循環(huán)調(diào)用它的next方法檢查是否有新消息需要處理:

[java]view plaincopy

publicstaticvoidloop()?{

finalLooper?me?=?myLooper();//獲取當(dāng)前線程looper

if(me?==null)?{

thrownewRuntimeException("No?Looper;?Looper.prepare()?wasn't?called?on?this?thread.");

}

finalMessageQueue?queue?=?me.mQueue;//獲取當(dāng)前線程MessageQueue

//?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();

finallongident?=?Binder.clearCallingIdentity();

for(;;)?{//不斷檢查是否有新消息需要處理

Message?msg?=?queue.next();//?might?block

if(msg?==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.println(">>>>>?Dispatching?to?"+?msg.target?+"?"+

msg.callback?+":?"+?msg.what);

}

//msg.target指向一個(gè)Handler對(duì)象,調(diào)用Handler的dispatchMessage方法分發(fā)消息

msg.target.dispatchMessage(msg);

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.

finallongnewIdent?=?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.recycleUnchecked();

}

}

2.MessageQueue的next方法中調(diào)用nativePollOnce函數(shù)檢查當(dāng)前線程的消息隊(duì)列中是否有新消息要處理,如果有消息會(huì)存在mMessage中并進(jìn)行處理:

[java]view plaincopy

Message?next()?{

//?Return?here?if?the?message?loop?has?already?quit?and?been?disposed.

//?This?can?happen?if?the?application?tries?to?restart?a?looper?after?quit

//?which?is?not?supported.

finallongptr?=?mPtr;

if(ptr?==0)?{

returnnull;

}

intpendingIdleHandlerCount?=?-1;//?-1?only?during?first?iteration

intnextPollTimeoutMillis?=0;//當(dāng)前線程需要進(jìn)入睡眠等待狀態(tài)的時(shí)間

for(;;)?{//不斷調(diào)用成員函數(shù)nativePollOnce來(lái)檢查當(dāng)前線程的消息隊(duì)列是否有新消息要處理

if(nextPollTimeoutMillis?!=0)?{

Binder.flushPendingCommands();

}

nativePollOnce(ptr,?nextPollTimeoutMillis);//..

synchronized(this)?{

//?Try?to?retrieve?the?next?message.??Return?if?found.

finallongnow?=?SystemClock.uptimeMillis();

Message?prevMsg?=null;

Message?msg?=?mMessages;//當(dāng)前線程需要處理的消息

if(msg?!=null&&?msg.target?==null)?{

//?Stalled?by?a?barrier.??Find?the?next?asynchronous?message?in?the?queue.

do{

prevMsg?=?msg;

msg?=?msg.next;

}while(msg?!=null&&?!msg.isAsynchronous());

}

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);

}else{

//?Got?a?message.

mBlocked?=false;

if(prevMsg?!=null)?{

prevMsg.next?=?msg.next;

}else{

mMessages?=?msg.next;

}

msg.next?=null;

if(DEBUG)?Log.v(TAG,"Returning?message:?"+?msg);

msg.markInUse();

returnmsg;

}

}else{

//?No?more?messages.

nextPollTimeoutMillis?=?-1;//沒(méi)有消息就睡覺(jué)

}

//?Process?the?quit?message?now?that?all?pending?messages?have?been?handled.

if(mQuitting)?{

dispose();

returnnull;

}

//?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))?{

pendingIdleHandlerCount?=?mIdleHandlers.size();

}

if(pendingIdleHandlerCount?<=0)?{

//?No?idle?handlers?to?run.??Loop?and?wait?some?more.

mBlocked?=true;

continue;

}

if(mPendingIdleHandlers?==null)?{

mPendingIdleHandlers?=newIdleHandler[Math.max(pendingIdleHandlerCount,4)];

}

mPendingIdleHandlers?=?mIdleHandlers.toArray(mPendingIdleHandlers);

}

//?Run?the?idle?handlers.

//?We?only?ever?reach?this?code?block?during?the?first?iteration.

for(inti?=0;?i?<?pendingIdleHandlerCount;?i++)?{

finalIdleHandler?idler?=?mPendingIdleHandlers[i];

mPendingIdleHandlers[i]?=null;//release?the?reference?to?the?handler

booleankeep?=false;

try{

keep?=?idler.queueIdle();

}catch(Throwable?t)?{

Log.wtf(TAG,"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;

//?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;

}

}

3.在nativePollOnce函數(shù)中調(diào)用Looper(Native)的pollOnce函數(shù)不斷檢查是否有新消息要處理:

[cpp]view plaincopy

staticvoidandroid_os_MessageQueue_nativePollOnce(JNIEnv*?env,?jobject?obj,jlong?ptr,?jint?timeoutMillis)?{

//通過(guò)ptr找到NativeMessageQueue

NativeMessageQueue*?nativeMessageQueue?=reinterpret_cast(ptr);

//調(diào)用nativeMessageQueue對(duì)象的pollOnce函數(shù)檢查當(dāng)前線程是否有新消息

nativeMessageQueue->pollOnce(env,?obj,?timeoutMillis);

}

4.在pollOnce函數(shù)中調(diào)用polllnner函數(shù)(返回值不等于0即有新消息):

[cpp]view plaincopy

voidNativeMessageQueue::pollOnce(JNIEnv*?env,?jobject?pollObj,inttimeoutMillis)?{

mPollEnv?=?env;

mPollObj?=?pollObj;

//調(diào)用Looper(Native)的pollOnce函數(shù)檢查當(dāng)前線程是否有新消息要處理

mLooper->pollOnce(timeoutMillis);

mPollObj?=?NULL;

mPollEnv?=?NULL;

if(mExceptionObj)?{

env->Throw(mExceptionObj);

env->DeleteLocalRef(mExceptionObj);

mExceptionObj?=?NULL;

}

}

----------------------------------------------------------分割線------------------------------------------------------------------

[java]view plaincopy

intLooper::pollOnce(inttimeoutMillis,int*?outFd,int*?outEvents,void**?outData)?{

intresult?=0;

for(;;)?{//不斷調(diào)用pollInner方法檢查是否有新消息

while(mResponseIndex?<?mResponses.size())?{

constResponse&?response?=?mResponses.itemAt(mResponseIndex++);

if(!?response.request.callback)?{

#ifDEBUG_POLL_AND_WAKE

LOGD("%p?~?pollOnce?-?returning?signalled?identifier?%d:?"

"fd=%d,?events=0x%x,?data=%p",this,

response.request.ident,?response.request.fd,

response.events,?response.request.data);

#endif

if(outFd?!=?NULL)?*outFd?=?response.request.fd;

if(outEvents?!=?NULL)?*outEvents?=?response.events;

if(outData?!=?NULL)?*outData?=?response.request.data;

returnresponse.request.ident;

}

}

if(result?!=0)?{

#ifDEBUG_POLL_AND_WAKE

LOGD("%p?~?pollOnce?-?returning?result?%d",this,?result);

#endif

if(outFd?!=?NULL)?*outFd?=0;

if(outEvents?!=?NULL)?*outEvents?=?NULL;

if(outData?!=?NULL)?*outData?=?NULL;

returnresult;

}

result?=?pollInner(timeoutMillis);//如果有新消息返回值不等于0

}

}

5.polllnner函數(shù)中調(diào)用awoken方法把管道中的舊數(shù)據(jù)清理掉:

[cpp]view plaincopy

intLooper::pollInner(inttimeoutMillis)?{

#if?DEBUG_POLL_AND_WAKE

LOGD("%p?~?pollOnce?-?waiting:?timeoutMillis=%d",this,?timeoutMillis);

#endif

intresult?=?ALOOPER_POLL_WAKE;

mResponses.clear();

mResponseIndex?=?0;

#ifdef?LOOPER_STATISTICS

nsecs_t?pollStartTime?=?systemTime(SYSTEM_TIME_MONOTONIC);

#endif

#ifdef?LOOPER_USES_EPOLL

structepoll_event?eventItems[EPOLL_MAX_EVENTS];

inteventCount?=?epoll_wait(mEpollFd,?eventItems,?EPOLL_MAX_EVENTS,?timeoutMillis);

boolacquiredLock?=false;

#else

//?Wait?for?wakeAndLock()?waiters?to?run?then?set?mPolling?to?true.

mLock.lock();

while(mWaiters?!=?0)?{

mResume.wait(mLock);

}

mPolling?=true;

mLock.unlock();

size_trequestedCount?=?mRequestedFds.size();

inteventCount?=?poll(mRequestedFds.editArray(),?requestedCount,?timeoutMillis);

#endif

if(eventCount?<?0)?{

if(errno?==?EINTR)?{

gotoDone;

}

LOGW("Poll?failed?with?an?unexpected?error,?errno=%d",?errno);

result?=?ALOOPER_POLL_ERROR;

gotoDone;

}

if(eventCount?==?0)?{

#if?DEBUG_POLL_AND_WAKE

LOGD("%p?~?pollOnce?-?timeout",this);

#endif

result?=?ALOOPER_POLL_TIMEOUT;

gotoDone;

}

#if?DEBUG_POLL_AND_WAKE

LOGD("%p?~?pollOnce?-?handling?events?from?%d?fds",this,?eventCount);

#endif

#ifdef?LOOPER_USES_EPOLL

for(inti?=?0;?i?<?eventCount;?i++)?{

intfd?=?eventItems[i].data.fd;

uint32_t?epollEvents?=?eventItems[i].events;

//判斷發(fā)生IO事件的文件描述符是否與當(dāng)前線程所關(guān)聯(lián)的管道的mWakeReadPipeFd一致

if(fd?==?mWakeReadPipeFd)?{

if(epollEvents?&?EPOLLIN)?{

awoken();

}else{

LOGW("Ignoring?unexpected?epoll?events?0x%x?on?wake?read?pipe.",?epollEvents);

}

}else{

if(!?acquiredLock)?{

mLock.lock();

acquiredLock?=true;

}

ssize_t?requestIndex?=?mRequests.indexOfKey(fd);

if(requestIndex?>=?0)?{

intevents?=?0;

if(epollEvents?&?EPOLLIN)?events?|=?ALOOPER_EVENT_INPUT;

if(epollEvents?&?EPOLLOUT)?events?|=?ALOOPER_EVENT_OUTPUT;

if(epollEvents?&?EPOLLERR)?events?|=?ALOOPER_EVENT_ERROR;

if(epollEvents?&?EPOLLHUP)?events?|=?ALOOPER_EVENT_HANGUP;

pushResponse(events,?mRequests.valueAt(requestIndex));

}else{

LOGW("Ignoring?unexpected?epoll?events?0x%x?on?fd?%d?that?is?"

"no?longer?registered.",?epollEvents,?fd);

}

}

}

if(acquiredLock)?{

mLock.unlock();

}

Done:?;

#else

for(size_ti?=?0;?i?<?requestedCount;?i++)?{

conststructpollfd&?requestedFd?=?mRequestedFds.itemAt(i);

shortpollEvents?=?requestedFd.revents;

if(pollEvents)?{

if(requestedFd.fd?==?mWakeReadPipeFd)?{

if(pollEvents?&?POLLIN)?{

awoken();

}else{

LOGW("Ignoring?unexpected?poll?events?0x%x?on?wake?read?pipe.",?pollEvents);

}

}else{

intevents?=?0;

if(pollEvents?&?POLLIN)?events?|=?ALOOPER_EVENT_INPUT;

if(pollEvents?&?POLLOUT)?events?|=?ALOOPER_EVENT_OUTPUT;

if(pollEvents?&?POLLERR)?events?|=?ALOOPER_EVENT_ERROR;

if(pollEvents?&?POLLHUP)?events?|=?ALOOPER_EVENT_HANGUP;

if(pollEvents?&?POLLNVAL)?events?|=?ALOOPER_EVENT_INVALID;

pushResponse(events,?mRequests.itemAt(i));

}

if(--eventCount?==?0)?{

break;

}

}

}

Done:

//?Set?mPolling?to?false?and?wake?up?the?wakeAndLock()?waiters.

mLock.lock();

mPolling?=false;

if(mWaiters?!=?0)?{

mAwake.broadcast();

}

mLock.unlock();

#endif

#ifdef?LOOPER_STATISTICS

nsecs_t?pollEndTime?=?systemTime(SYSTEM_TIME_MONOTONIC);

mSampledPolls?+=?1;

if(timeoutMillis?==?0)?{

mSampledZeroPollCount?+=?1;

mSampledZeroPollLatencySum?+=?pollEndTime?-?pollStartTime;

}elseif(timeoutMillis?>?0?&&?result?==?ALOOPER_POLL_TIMEOUT)?{

mSampledTimeoutPollCount?+=?1;

mSampledTimeoutPollLatencySum?+=?pollEndTime?-?pollStartTime

-?milliseconds_to_nanoseconds(timeoutMillis);

}

if(mSampledPolls?==?SAMPLED_POLLS_TO_AGGREGATE)?{

LOGD("%p?~?poll?latency?statistics:?%0.3fms?zero?timeout,?%0.3fms?non-zero?timeout",this,

0.000001f?*float(mSampledZeroPollLatencySum)?/?mSampledZeroPollCount,

0.000001f?*float(mSampledTimeoutPollLatencySum)?/?mSampledTimeoutPollCount);

mSampledPolls?=?0;

mSampledZeroPollCount?=?0;

mSampledZeroPollLatencySum?=?0;

mSampledTimeoutPollCount?=?0;

mSampledTimeoutPollLatencySum?=?0;

}

#endif

for(size_ti?=?0;?i?<?mResponses.size();?i++)?{

constResponse&?response?=?mResponses.itemAt(i);

if(response.request.callback)?{

#if?DEBUG_POLL_AND_WAKE?||?DEBUG_CALLBACKS

LOGD("%p?~?pollOnce?-?invoking?callback:?fd=%d,?events=0x%x,?data=%p",this,

response.request.fd,?response.events,?response.request.data);

#endif

intcallbackResult?=?response.request.callback(

response.request.fd,?response.events,?response.request.data);

if(callbackResult?==?0)?{

removeFd(response.request.fd);

}

result?=?ALOOPER_POLL_CALLBACK;

}

}

returnresult;

}

6.awoken方法的實(shí)現(xiàn):

[cpp]view plaincopy

voidLooper::awoken()?{

#if?DEBUG_POLL_AND_WAKE

LOGD("%p?~?awoken",this);

#endif

#ifdef?LOOPER_STATISTICS

if(mPendingWakeCount?==?0)?{

LOGD("%p?~?awoken:?spurious!",this);

}else{

mSampledWakeCycles?+=?1;

mSampledWakeCountSum?+=?mPendingWakeCount;

mSampledWakeLatencySum?+=?systemTime(SYSTEM_TIME_MONOTONIC)?-?mPendingWakeTime;

mPendingWakeCount?=?0;

mPendingWakeTime?=?-1;

if(mSampledWakeCycles?==?SAMPLED_WAKE_CYCLES_TO_AGGREGATE)?{

LOGD("%p?~?wake?statistics:?%0.3fms?wake?latency,?%0.3f?wakes?per?cycle",this,

0.000001f?*float(mSampledWakeLatencySum)?/?mSampledWakeCycles,

float(mSampledWakeCountSum)?/?mSampledWakeCycles);

mSampledWakeCycles?=?0;

mSampledWakeCountSum?=?0;

mSampledWakeLatencySum?=?0;

}

}

#endif

charbuffer[16];

ssize_t?nRead;

do{

nRead?=?read(mWakeReadPipeFd,?buffer,sizeof(buffer));//將管道中數(shù)據(jù)讀出來(lái)

}while((nRead?==?-1?&&?errno?==?EINTR)?||?nRead?==sizeof(buffer));

}

線程消息發(fā)送過(guò)程

1.通過(guò)調(diào)用sendMessageXXX方法將消息發(fā)送到一個(gè)消息隊(duì)列中:

[java]view plaincopy

publicbooleansendMessageAtTime(Message?msg,longuptimeMillis)

{

booleansent?=false;

MessageQueue?queue?=?mQueue;

if(queue?!=null)?{

msg.target?=this;

sent?=?queue.enqueueMessage(msg,?uptimeMillis);//將消息發(fā)送到消息隊(duì)列中

}

else{

RuntimeException?e?=newRuntimeException(

this+"?sendMessageAtTime()?called?with?no?mQueue");

Log.w("Looper",?e.getMessage(),?e);

}

returnsent;

}

2.調(diào)用enqueueMessage方法將消息插入到消息隊(duì)列(隊(duì)頭或隊(duì)中):

[java]view plaincopy

booleanenqueueMessage(Message?msg,longwhen)?{

if(msg.target?==null)?{

thrownewIllegalArgumentException("Message?must?have?a?target.");

}

if(msg.isInUse())?{

thrownewIllegalStateException(msg?+"?This?message?is?already?in?use.");

}

synchronized(this)?{

if(mQuitting)?{

IllegalStateException?e?=newIllegalStateException(

msg.target?+"?sending?message?to?a?Handler?on?a?dead?thread");

Log.w(TAG,?e.getMessage(),?e);

msg.recycle();

returnfalse;

}

msg.markInUse();

msg.when?=?when;

Message?p?=?mMessages;

booleanneedWake;

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)前線程是否處于睡眠等待狀態(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();

Message?prev;

for(;;)?{

prev?=?p;

p?=?p.next;

if(p?==null||?when?<?p.when)?{

break;

}

if(needWake?&&?p.isAsynchronous())?{

needWake?=false;

}

}

msg.next?=?p;//?invariant:?p?==?prev.next,將消息插入到消息隊(duì)列中

prev.next?=?msg;

}

//?We?can?assume?mPtr?!=?0?because?mQuitting?is?false.

if(needWake)?{

nativeWake(mPtr);//如果線程正在睡眠,那么將其喚醒

}

}

returntrue;

3.如果線程處于睡眠狀態(tài)調(diào)用NativeMessageQueue的nativeWake方法,喚醒他:

[cpp]view plaincopy

staticvoidandroid_os_MessageQueue_nativeWake(JNIEnv*?env,?jclass?clazz,?jlong?ptr)?{

NativeMessageQueue?*nativeMessageQueue?=reinterpret_cast(ptr);

//通過(guò)ptr找到NativeMessageQueue,并調(diào)用它的wake方法喚醒目標(biāo)線程,讓它處理消息

nativeMessageQueue->wake();

}

4.nativeWake方法中調(diào)用NativeMessageQueue的wake方法:

[cpp]view plaincopy

voidNativeMessageQueue::wake()?{

mLooper->wake();//調(diào)用Looper(Native)的wake方法

}

5.wake方法中調(diào)用Looper(Native)的wake方法,向管道寫(xiě)入字符:

[cpp]view plaincopy

voidLooper::wake()?{

#if?DEBUG_POLL_AND_WAKE

LOGD("%p?~?wake",this);

#endif

#ifdef?LOOPER_STATISTICS

//?FIXME:?Possible?race?with?awoken()?but?this?code?is?for?testing?only?and?is?rarely?enabled.

if(mPendingWakeCount++?==?0)?{

mPendingWakeTime?=?systemTime(SYSTEM_TIME_MONOTONIC);

}

#endif

ssize_t?nWrite;

do{

nWrite?=?write(mWakeWritePipeFd,"W",?1);//向管道中寫(xiě)入字符,喚醒線程。

}while(nWrite?==?-1?&&?errno?==?EINTR);

if(nWrite?!=?1)?{

if(errno?!=?EAGAIN)?{

LOGW("Could?not?write?wake?signal,?errno=%d",?errno);

}

}

}

線程消息處理過(guò)程

1.通過(guò)Looper類的loop方法獲取消息:

[java]view plaincopy

publicstaticvoidloop()?{

finalLooper?me?=?myLooper();//獲取當(dāng)前線程looper

if(me?==null)?{

thrownewRuntimeException("No?Looper;?Looper.prepare()?wasn't?called?on?this?thread.");

}

finalMessageQueue?queue?=?me.mQueue;//獲取當(dāng)前線程MessageQueue

//?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();

finallongident?=?Binder.clearCallingIdentity();

for(;;)?{//不斷檢查是否有新消息需要處理

Message?msg?=?queue.next();//?might?block

if(msg?==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.println(">>>>>?Dispatching?to?"+?msg.target?+"?"+

msg.callback?+":?"+?msg.what);

}

//msg.target指向一個(gè)Handler對(duì)象,調(diào)用Handler的dispatchMessage方法分發(fā)消息

msg.target.dispatchMessage(msg);

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.

finallongnewIdent?=?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.recycleUnchecked();

}

}

2.通過(guò)Handler類的dispatchMessage分發(fā)消息:

[java]view plaincopy

//分發(fā)Looper傳來(lái)的消息

publicvoiddispatchMessage(Message?msg)?{

if(msg.callback?!=null)?{

handleCallback(msg);

}else{

if(mCallback?!=null)?{

if(mCallback.handleMessage(msg))?{

return;

}

}

handleMessage(msg);

}

}

3.通過(guò)Handler的成員函數(shù)handleMessage處理消息:

[java]view plaincopy

//通過(guò)重寫(xiě)handleMessage方法處理消息

publicvoidhandleMessage(Message?msg)?{????}


===================================================

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容