消息機(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)?{????}
===================================================