Android消息機(jī)制不完全解析(下)
? ? 接著上一篇文章Android消息機(jī)制不完全解析(上),接著看C++部分的實(shí)現(xiàn)。
? ? 首先,看看在/frameworks/base/core/jni/android_os_MessageQueue.cpp文件中看看android.os.MessageQueue類(lèi)中的四個(gè)原生函數(shù)的實(shí)現(xiàn):
static?void?android_os_MessageQueue_nativeInit(JNIEnv*?env,?jobject?obj)?{
????NativeMessageQueue*?nativeMessageQueue?=?new?NativeMessageQueue();//構(gòu)造NativeMessageQueue實(shí)例
????if?(!nativeMessageQueue)?{
????????jniThrowRuntimeException(env,?"Unable?to?allocate?native?queue");
????????return;
????}
????nativeMessageQueue->incStrong(env);//強(qiáng)引用+1
????android_os_MessageQueue_setNativeMessageQueue(env,?obj,?nativeMessageQueue);
}
static?void?android_os_MessageQueue_nativeDestroy(JNIEnv*?env,?jobject?obj)?{
????NativeMessageQueue*?nativeMessageQueue?=
????????????android_os_MessageQueue_getNativeMessageQueue(env,?obj);
????if?(nativeMessageQueue)?{
????????android_os_MessageQueue_setNativeMessageQueue(env,?obj,?NULL);
????????nativeMessageQueue->decStrong(env);//強(qiáng)引用-1,實(shí)際上會(huì)導(dǎo)致釋放NativeMessageQueue實(shí)例
????}
}
static?void?android_os_MessageQueue_nativePollOnce(JNIEnv*?env,?jobject?obj,
????????jint?ptr,?jint?timeoutMillis)?{
????NativeMessageQueue*?nativeMessageQueue?=?reinterpret_cast(ptr);//指針強(qiáng)制轉(zhuǎn)換
????nativeMessageQueue->pollOnce(env,?timeoutMillis);//調(diào)用nativeMessageQueue的pollonce函數(shù)
}
static?void?android_os_MessageQueue_nativeWake(JNIEnv*?env,?jobject?obj,?jint?ptr)?{
????NativeMessageQueue*?nativeMessageQueue?=?reinterpret_cast(ptr);
????return?nativeMessageQueue->wake();//調(diào)用nativeMessageQueue的wake函數(shù)
}? ? 從代碼中,可以看到這四個(gè)函數(shù)的實(shí)現(xiàn)都是依賴于NativeMessageQueue類(lèi)。不過(guò),在開(kāi)始解析NativeMessageQueue之前,我們?cè)倏匆恍┯幸馑嫉拇a:
static?void?android_os_MessageQueue_setNativeMessageQueue(JNIEnv*?env,?jobject?messageQueueObj,
????????NativeMessageQueue*?nativeMessageQueue)?{
????env->SetIntField(messageQueueObj,?gMessageQueueClassInfo.mPtr,
?????????????reinterpret_cast(nativeMessageQueue));//把nativeMessageQueue的實(shí)例地址強(qiáng)轉(zhuǎn)為java的int類(lèi)型并保存到gMessageQueueClassInfo.mPtr中
}? ? 那么gMessageQueueClassInfo.mPtr是什么呢?
static?JNINativeMethod?gMessageQueueMethods[]?=?{
????/*?name,?signature,?funcPtr?*/
????{?"nativeInit",?"()V",?(void*)android_os_MessageQueue_nativeInit?},
????{?"nativeDestroy",?"()V",?(void*)android_os_MessageQueue_nativeDestroy?},
????{?"nativePollOnce",?"(II)V",?(void*)android_os_MessageQueue_nativePollOnce?},
????{?"nativeWake",?"(I)V",?(void*)android_os_MessageQueue_nativeWake?}
};
#define?FIND_CLASS(var,?className)?
????????var?=?env->FindClass(className);?
????????LOG_FATAL_IF(!?var,?"Unable?to?find?class?"?className);
#define?GET_FIELD_ID(var,?clazz,?fieldName,?fieldDescriptor)?
????????var?=?env->GetFieldID(clazz,?fieldName,?fieldDescriptor);?
????????LOG_FATAL_IF(!?var,?"Unable?to?find?field?"?fieldName);
//這個(gè)函數(shù)在Android啟動(dòng)的時(shí)候,會(huì)被系統(tǒng)調(diào)用
int?register_android_os_MessageQueue(JNIEnv*?env)?{
????int?res?=?jniRegisterNativeMethods(env,?"android/os/MessageQueue",
????????????gMessageQueueMethods,?NELEM(gMessageQueueMethods));//關(guān)聯(lián)MessageQueueQueue的原生函數(shù)
????LOG_FATAL_IF(res?<?0,?"Unable?to?register?native?methods.");
????jclass?clazz;
????FIND_CLASS(clazz,?"android/os/MessageQueue");//獲取MessageQueue的class
????GET_FIELD_ID(gMessageQueueClassInfo.mPtr,?clazz,
????????????"mPtr",?"I");//獲取MessageQueue?class的mPtr?field的Id
????
????return?0;
}? ? 上面的代碼很像java的反射有木有?
????Class?cls?=?Class.forName("android.os.MessageQueue");
????Field?feild?=?cls.getField("mPtr");? ? 到這里,我們就明白了android_os_MessageQueue_setNativeMessageQueue函數(shù)實(shí)際上把a(bǔ)ndroid.os.MessageQueue實(shí)例的mPtr值設(shè)置為nativeMessageQueue實(shí)例的地址。雖然Java語(yǔ)言沒(méi)有指針的說(shuō)法,但是,這里的mPtr卻的的確確是作為一個(gè)指針使用的?,F(xiàn)在,我們也就理解了,為什么mPtr可以被強(qiáng)制轉(zhuǎn)換為nativeMessageQueue了。
? ? 小結(jié):
android_os_MessageQueue_nativeInit和android_os_MessageQueue_nativeDestory兩個(gè)函數(shù)做了些什么:
android_os_MessageQueue_nativeInit:構(gòu)造NativeMessageQueue實(shí)例android_os_MessageQueue_nativeDestory:銷(xiāo)毀NativeMessageQeue實(shí)例NativeMessageQueue
? ? 先來(lái)看看NativeMessageQueue的聲明:
class?NativeMessageQueue?:?public?MessageQueue?{
public:
????NativeMessageQueue();
????virtual?~NativeMessageQueue();
????virtual?void?raiseException(JNIEnv*?env,?const?char*?msg,?jthrowable?exceptionObj);
????void?pollOnce(JNIEnv*?env,?int?timeoutMillis);
????void?wake();
private:
????bool?mInCallback;
????jthrowable?mExceptionObj;
};? ? NativeMessageQueue繼承自MessageQueue(不是java中的android.os.MessageQueue哦),關(guān)于MessageQueue我們只需要了解,它包含了一個(gè)成員mLooper即可(有興趣的同學(xué)可以查看/frameworks/base/core/jni/android_os_MessageQueue.h) ? ?
class?MessageQueue??{
????......
protected:
????spmLooper;
};? ? 繼續(xù)看NativeMessageQueue的代碼:
NativeMessageQueue::NativeMessageQueue()?:?mInCallback(false),?mExceptionObj(NULL)?{
????mLooper?=?Looper::getForThread();
????if?(mLooper?==?NULL)?{
????????mLooper?=?new?Looper(false);//實(shí)例化mLooper
????????Looper::setForThread(mLooper);
????}
}? ? NativeMessageQueue構(gòu)造實(shí)例的時(shí)候,會(huì)實(shí)例化mLooper。
void?NativeMessageQueue::pollOnce(JNIEnv*?env,?int?timeoutMillis)?{
????mInCallback?=?true;
????mLooper->pollOnce(timeoutMillis);
????mInCallback?=?false;
????if?(mExceptionObj)?{
????????env->Throw(mExceptionObj);
????????env->DeleteLocalRef(mExceptionObj);
????????mExceptionObj?=?NULL;
????}
}
void?NativeMessageQueue::wake()?{
????mLooper->wake();
}? ? 小結(jié):
NativeMessageQueue的函數(shù)pollonce和wake實(shí)現(xiàn)相當(dāng)簡(jiǎn)單,交給mLooper的同名函數(shù)。
Looper
? ? 先來(lái)看看Looper的聲明/frameworks/native/include/utils/Looper.h:
class?Looper?:?public?ALooper,?public?RefBase?{
protected:
????virtual?~Looper();
public:
????Looper(bool?allowNonCallbacks);
????bool?getAllowNonCallbacks()?const;
????int?pollOnce(int?timeoutMillis,?int*?outFd,?int*?outEvents,?void**?outData);
????inline?int?pollOnce(int?timeoutMillis)?{
????????return?pollOnce(timeoutMillis,?NULL,?NULL,?NULL);
????}
????void?wake();
private:
????const?bool?mAllowNonCallbacks;?//?immutable
????int?mWakeReadPipeFd;??//?immutable
????int?mWakeWritePipeFd;?//?immutable
????Mutex?mLock;
????int?mEpollFd;?//?immutable
????int?pollInner(int?timeoutMillis);
????void?awoken();
};? ? 因?yàn)榇a有點(diǎn)多,所以上面的聲明,已經(jīng)被我精簡(jiǎn)了大部分,現(xiàn)在我們只關(guān)注我們關(guān)心的:pollonce和wake函數(shù)。
? ? 還是從構(gòu)造函數(shù)開(kāi)始(frameworks/native/utils/Looper.cpp):
Looper::Looper(bool?allowNonCallbacks)?:
????????mAllowNonCallbacks(allowNonCallbacks),?mSendingMessage(false),
????????mResponseIndex(0),?mNextMessageUptime(LLONG_MAX)?{
????int?wakeFds[2];
????int?result?=?pipe(wakeFds);//創(chuàng)建命名管道
????LOG_ALWAYS_FATAL_IF(result?!=?0,?"Could?not?create?wake?pipe.??errno=%d",?errno);
????//?保存命名管道
????mWakeReadPipeFd?=?wakeFds[0];
????mWakeWritePipeFd?=?wakeFds[1];
????result?=?fcntl(mWakeReadPipeFd,?F_SETFL,?O_NONBLOCK);//設(shè)置為非阻塞模式
????LOG_ALWAYS_FATAL_IF(result?!=?0,?"Could?not?make?wake?read?pipe?non-blocking.??errno=%d",
????????????errno);
????result?=?fcntl(mWakeWritePipeFd,?F_SETFL,?O_NONBLOCK);//設(shè)置為非阻塞模式
????LOG_ALWAYS_FATAL_IF(result?!=?0,?"Could?not?make?wake?write?pipe?non-blocking.??errno=%d",
????????????errno);
????//?開(kāi)始使用epoll?API,實(shí)現(xiàn)輪詢
????//?Allocate?the?epoll?instance?and?register?the?wake?pipe.
????mEpollFd?=?epoll_create(EPOLL_SIZE_HINT);//創(chuàng)建epoll文件描述符
????LOG_ALWAYS_FATAL_IF(mEpollFd?<?0,?"Could?not?create?epoll?instance.??errno=%d",?errno);
????struct?epoll_event?eventItem;
????memset(&?eventItem,?0,?sizeof(epoll_event));?//?zero?out?unused?members?of?data?field?union
????eventItem.events?=?EPOLLIN;
????eventItem.data.fd?=?mWakeReadPipeFd;
????result?=?epoll_ctl(mEpollFd,?EPOLL_CTL_ADD,?mWakeReadPipeFd,?&?eventItem);?//?把剛才創(chuàng)建的命名管道的讀端加入的到epoll的監(jiān)聽(tīng)隊(duì)列中
????LOG_ALWAYS_FATAL_IF(result?!=?0,?"Could?not?add?wake?read?pipe?to?epoll?instance.??errno=%d",
????????????errno);
}
Looper::~Looper()?{
????close(mWakeReadPipeFd);//釋放命名管道
????close(mWakeWritePipeFd);
????close(mEpollFd);//釋放epoll文件描述符
}? ? Looper的構(gòu)造函數(shù)中,出現(xiàn)了命名管道和epoll相關(guān)的代碼,這是為什么呢?別急,接著看下去就知道了:
int?Looper::pollOnce(int?timeoutMillis,?int*?outFd,?int*?outEvents,?void**?outData)?{
????int?result?=?0;
????for?(;;)?{
???????//?這段代碼暫時(shí)無(wú)視
???????while?(mResponseIndex?<?mResponses.size())?{
????????????const?Response&?response?=?mResponses.itemAt(mResponseIndex++);
????????????int?ident?=?response.request.ident;
????????????if?(ident?>=?0)?{//ident?>?0,?即此response為noncallback,需要返回event,data等數(shù)據(jù)給調(diào)用者處理
????????????????int?fd?=?response.request.fd;
????????????????int?events?=?response.events;
????????????????void*?data?=?response.request.data;
#if?DEBUG_POLL_AND_WAKE
????????????????ALOGD("%p?~?pollOnce?-?returning?signalled?identifier?%d:?"
????????????????????????"fd=%d,?events=0x%x,?data=%p",
????????????????????????this,?ident,?fd,?events,?data);
#endif
????????????????if?(outFd?!=?NULL)?*outFd?=?fd;
????????????????if?(outEvents?!=?NULL)?*outEvents?=?events;
????????????????if?(outData?!=?NULL)?*outData?=?data;
????????????????return?ident;
????????????}
????????}
????????if?(result?!=?0)?{
#if?DEBUG_POLL_AND_WAKE
????????????ALOGD("%p?~?pollOnce?-?returning?result?%d",?this,?result);
#endif
????????????if?(outFd?!=?NULL)?*outFd?=?0;
????????????if?(outEvents?!=?NULL)?*outEvents?=?0;
????????????if?(outData?!=?NULL)?*outData?=?NULL;
????????????return?result;
????????}
????????result?=?pollInner(timeoutMillis);//這一行才是重點(diǎn)!
????}
}? ? 接著往下看,代碼有些長(zhǎng),但請(qǐng)仔細(xì)看:
int?Looper::pollInner(int?timeoutMillis)?{
????
#if?DEBUG_POLL_AND_WAKE
????ALOGD("%p?~?pollOnce?-?waiting:?timeoutMillis=%d",?this,?timeoutMillis);
#endif
????//?設(shè)置timeoutMillis的值為Math.min(timeoutMills,?mNextMessageUptime)
????//?Adjust?the?timeout?based?on?when?the?next?message?is?due.
????if?(timeoutMillis?!=?0?&&?mNextMessageUptime?!=?LLONG_MAX)?{
????????nsecs_t?now?=?systemTime(SYSTEM_TIME_MONOTONIC);
????????int?messageTimeoutMillis?=?toMillisecondTimeoutDelay(now,?mNextMessageUptime);
????????if?(messageTimeoutMillis?>=?0
????????????????&&?(timeoutMillis?<?0?||?messageTimeoutMillis?<?timeoutMillis))?{
????????????timeoutMillis?=?messageTimeoutMillis;
????????}
#if?DEBUG_POLL_AND_WAKE
????????ALOGD("%p?~?pollOnce?-?next?message?in?%lldns,?adjusted?timeout:?timeoutMillis=%d",
????????????????this,?mNextMessageUptime?-?now,?timeoutMillis);
#endif
????}
????//?Poll.
????int?result?=?ALOOPER_POLL_WAKE;
????mResponses.clear();
????mResponseIndex?=?0;
????//?開(kāi)始輪詢
????struct?epoll_event?eventItems[EPOLL_MAX_EVENTS];
????int?eventCount?=?epoll_wait(mEpollFd,?eventItems,?EPOLL_MAX_EVENTS,?timeoutMillis);
????//?Acquire?lock.
????mLock.lock();
????//?Check?for?poll?error.
????if?(eventCount?<?0)?{?//處理error
????????if?(errno?==?EINTR)?{
????????????goto?Done;
????????}
????????ALOGW("Poll?failed?with?an?unexpected?error,?errno=%d",?errno);
????????result?=?ALOOPER_POLL_ERROR;
????????goto?Done;
????}
????//?Check?for?poll?timeout.
????if?(eventCount?==?0)?{?//?未能等到event,故timeout
#if?DEBUG_POLL_AND_WAKE
????????ALOGD("%p?~?pollOnce?-?timeout",?this);
#endif
????????result?=?ALOOPER_POLL_TIMEOUT;
????????goto?Done;
????}
????//?Handle?all?events.
#if?DEBUG_POLL_AND_WAKE
????ALOGD("%p?~?pollOnce?-?handling?events?from?%d?fds",?this,?eventCount);
#endif
????for?(int?i?=?0;?i?<?eventCount;?i++)?{//有event,則處理
????????int?fd?=?eventItems[i].data.fd;
????????uint32_t?epollEvents?=?eventItems[i].events;
????????if?(fd?==?mWakeReadPipeFd)?{
????????????if?(epollEvents?&?EPOLLIN)?{
????????????????awoken();//讀取命名管道內(nèi)的數(shù)據(jù)
????????????}?else?{
????????????????ALOGW("Ignoring?unexpected?epoll?events?0x%x?on?wake?read?pipe.",?epollEvents);
????????????}
????????}?else?{
????????????ssize_t?requestIndex?=?mRequests.indexOfKey(fd);
????????????if?(requestIndex?>=?0)?{
????????????????int?events?=?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));//把event添加到mResponses中,等待后續(xù)處理
????????????}?else?{
????????????????ALOGW("Ignoring?unexpected?epoll?events?0x%x?on?fd?%d?that?is?"
????????????????????????"no?longer?registered.",?epollEvents,?fd);
????????????}
????????}
????}
Done:?;
????//?處理C++層的Message
????//?Invoke?pending?message?callbacks.
????mNextMessageUptime?=?LLONG_MAX;
????while?(mMessageEnvelopes.size()?!=?0)?{
????????nsecs_t?now?=?systemTime(SYSTEM_TIME_MONOTONIC);
????????const?MessageEnvelope&?messageEnvelope?=?mMessageEnvelopes.itemAt(0);
????????if?(messageEnvelope.uptime?<=?now)?{
????????????//?Remove?the?envelope?from?the?list.
????????????//?We?keep?a?strong?reference?to?the?handler?until?the?call?to?handleMessage
????????????//?finishes.??Then?we?drop?it?so?that?the?handler?can?be?deleted?*before*
????????????//?we?reacquire?our?lock.
????????????{?//?obtain?handler
????????????????sphandler?=?messageEnvelope.handler;
????????????????Message?message?=?messageEnvelope.message;
????????????????mMessageEnvelopes.removeAt(0);
????????????????mSendingMessage?=?true;
????????????????mLock.unlock();
#if?DEBUG_POLL_AND_WAKE?||?DEBUG_CALLBACKS
????????????????ALOGD("%p?~?pollOnce?-?sending?message:?handler=%p,?what=%d",
????????????????????????this,?handler.get(),?message.what);
#endif
????????????????handler->handleMessage(message);//調(diào)用handler->handleMessage
????????????}?//?release?handler
????????????mLock.lock();
????????????mSendingMessage?=?false;
????????????result?=?ALOOPER_POLL_CALLBACK;
????????}?else?{
????????????//?The?last?message?left?at?the?head?of?the?queue?determines?the?next?wakeup?time.
????????????mNextMessageUptime?=?messageEnvelope.uptime;//更新mNextMessageUptime
????????????break;
????????}
????}
????//?Release?lock.
????mLock.unlock();
????//?處理mResponses
????//?Invoke?all?response?callbacks.
????for?(size_t?i?=?0;?i?<?mResponses.size();?i++)?{
????????Response&?response?=?mResponses.editItemAt(i);
????????if?(response.request.ident?==?ALOOPER_POLL_CALLBACK)?{
????????????int?fd?=?response.request.fd;
????????????int?events?=?response.events;
????????????void*?data?=?response.request.data;
#if?DEBUG_POLL_AND_WAKE?||?DEBUG_CALLBACKS
????????????ALOGD("%p?~?pollOnce?-?invoking?fd?event?callback?%p:?fd=%d,?events=0x%x,?data=%p",
????????????????????this,?response.request.callback.get(),?fd,?events,?data);
#endif
????????????int?callbackResult?=?response.request.callback->handleEvent(fd,?events,?data);//調(diào)用callback->handleEvent
????????????if?(callbackResult?==?0)?{
????????????????removeFd(fd);
????????????}
????????????//?Clear?the?callback?reference?in?the?response?structure?promptly?because?we
????????????//?will?not?clear?the?response?vector?itself?until?the?next?poll.
????????????response.request.callback.clear();
????????????result?=?ALOOPER_POLL_CALLBACK;
????????}
????}
????return?result;
}? ? 代碼比較長(zhǎng),所以分段分析:
????//?設(shè)置timeoutMillis的值為Math.min(timeoutMillis,?mNextMessageUptime)
????//?Adjust?the?timeout?based?on?when?the?next?message?is?due.
????if?(timeoutMillis?!=?0?&&?mNextMessageUptime?!=?LLONG_MAX)?{
????????nsecs_t?now?=?systemTime(SYSTEM_TIME_MONOTONIC);
????????int?messageTimeoutMillis?=?toMillisecondTimeoutDelay(now,?mNextMessageUptime);
????????if?(messageTimeoutMillis?>=?0
????????????????&&?(timeoutMillis?<?0?||?messageTimeoutMillis?<?timeoutMillis))?{
????????????timeoutMillis?=?messageTimeoutMillis;
????????}#if?DEBUG_POLL_AND_WAKE
????????ALOGD("%p?~?pollOnce?-?next?message?in?%lldns,?adjusted?timeout:?timeoutMillis=%d",
????????????????this,?mNextMessageUptime?-?now,?timeoutMillis);
#endif
????}? ? 為了解析這段代碼,需要先補(bǔ)充一些C++層的Message相關(guān)的代碼:
struct?Message?{
????Message()?:?what(0)?{?}
????Message(int?what)?:?what(what)?{?}
????/*?The?message?type.?(interpretation?is?left?up?to?the?handler)?*/
????int?what;
};
class?MessageHandler?:?public?virtual?RefBase?{
????protected:
????????virtual?~MessageHandler()?{?}
????public:
????????/**
?????????*?Handles?a?message.
?????????*/
????????virtual?void?handleMessage(const?Message&?message)?=?0;
}
struct?MessageEnvelope?{
????MessageEnvelope()?:?uptime(0)?{?}
????MessageEnvelope(nsecs_t?uptime,?const?sphandler,const?Message&?message)?:?uptime(uptime),?handler(handler),?message(message)?{}
????nsecs_t?uptime;
????MessageHandler>?handler;
????Message?message;
};
void?Looper::sendMessage(const?sp&?handler,?const?Message&?message)?{
????nsecs_t?now?=?systemTime(SYSTEM_TIME_MONOTONIC);
????sendMessageAtTime(now,?handler,?message);
}
void?Looper::sendMessageDelayed(nsecs_t?uptimeDelay,?const?sp&?handler,
????????const?Message&?message)?{
????nsecs_t?now?=?systemTime(SYSTEM_TIME_MONOTONIC);
????sendMessageAtTime(now?+?uptimeDelay,?handler,?message);
}
void?Looper::sendMessageAtTime(nsecs_t?uptime,?const?sp&?handler,
????????const?Message&?message)?{
#if?DEBUG_CALLBACKS
????ALOGD("%p?~?sendMessageAtTime?-?uptime=%lld,?handler=%p,?what=%d",
????????????this,?uptime,?handler.get(),?message.what);
#endif
????size_t?i?=?0;
????{?//?acquire?lock
????????AutoMutex?_l(mLock);
????????size_t?messageCount?=?mMessageEnvelopes.size();
????????while?(i?<?messageCount?&&?uptime?>=?mMessageEnvelopes.itemAt(i).uptime)?{
????????????i?+=?1;
????????}
????????MessageEnvelope?messageEnvelope(uptime,?handler,?message);
????????mMessageEnvelopes.insertAt(messageEnvelope,?i,?1);
????????//?Optimization:?If?the?Looper?is?currently?sending?a?message,?then?we?can?skip
????????//?the?call?to?wake()?because?the?next?thing?the?Looper?will?do?after?processing
????????//?messages?is?to?decide?when?the?next?wakeup?time?should?be.??In?fact,?it?does
????????//?not?even?matter?whether?this?code?is?running?on?the?Looper?thread.
????????if?(mSendingMessage)?{
????????????return;
????????}
????}?//?release?lock
????//?Wake?the?poll?loop?only?when?we?enqueue?a?new?message?at?the?head.
????if?(i?==?0)?{
????????wake();
????}
}
void?Looper::removeMessages(const?sp&?handler)?{
#if?DEBUG_CALLBACKS
????ALOGD("%p?~?removeMessages?-?handler=%p",?this,?handler.get());
#endif
????{?//?acquire?lock
????????AutoMutex?_l(mLock);
????????for?(size_t?i?=?mMessageEnvelopes.size();?i?!=?0;?)?{
????????????const?MessageEnvelope&?messageEnvelope?=?mMessageEnvelopes.itemAt(--i);
????????????if?(messageEnvelope.handler?==?handler)?{
????????????????mMessageEnvelopes.removeAt(i);
????????????}
????????}
????}?//?release?lock
}
void?Looper::removeMessages(const?sp&?handler,?int?what)?{
#if?DEBUG_CALLBACKS
????ALOGD("%p?~?removeMessages?-?handler=%p,?what=%d",?this,?handler.get(),?what);
#endif
????{?//?acquire?lock
????????AutoMutex?_l(mLock);
????????for?(size_t?i?=?mMessageEnvelopes.size();?i?!=?0;?)?{
????????????const?MessageEnvelope&?messageEnvelope?=?mMessageEnvelopes.itemAt(--i);
????????????if?(messageEnvelope.handler?==?handler
????????????????????&&?messageEnvelope.message.what?==?what)?{
????????????????mMessageEnvelopes.removeAt(i);
????????????}
????????}
????}?//?release?lock
}? ? 是不是覺(jué)得上面的代碼似曾相識(shí)?和Java層的MessageQueue很像似有木有?和java層一樣,C++層存在消息隊(duì)列和消息處理機(jī)制,消息被保存到成員mMessageEvelopes中,并在pollInner函數(shù)中處理消息(調(diào)用MesageHandler的handleMesage函數(shù)處理)。
? ? 現(xiàn)在回到Looper::pollonceh函數(shù),我們就應(yīng)該能夠理解,pollOnce函數(shù)到timeOutMillis參數(shù)僅僅代表了Java層下一個(gè)Message的觸發(fā)延遲,所以,我們還需要考慮C++層下一個(gè)Message的觸發(fā)延遲,所以,代碼設(shè)置timeoutMillis為timeoutMillis和mNextMessageUpTime中的較小值。
? ? 繼續(xù)下一段代碼:
????int?result?=?ALOOPER_POLL_WAKE; ????mResponses.clear(); ????mResponseIndex?=?0; ????//?開(kāi)始輪詢 ????struct?epoll_event?eventItems[EPOLL_MAX_EVENTS]; ????int?eventCount?=?epoll_wait(mEpollFd,?eventItems,?EPOLL_MAX_EVENTS,?timeoutMillis); ????//?Acquire?lock. ????mLock.lock();
? ? 調(diào)用epoll函數(shù),等待event發(fā)生,epoll_wait函數(shù)的返回值有三種可能:失敗出錯(cuò)、沒(méi)有event、有一個(gè)或多個(gè)event。
1. 失敗的處理:
????//?Check?for?poll?error.
????if?(eventCount?<?0)?{?//處理error
????????if?(errno?==?EINTR)?{
????????????goto?Done;
????????}
????????ALOGW("Poll?failed?with?an?unexpected?error,?errno=%d",?errno);
????????result?=?ALOOPER_POLL_ERROR;
????????goto?Done;
????}2. 沒(méi)有event發(fā)生:
????//?Check?for?poll?timeout.
????if?(eventCount?==?0)?{?//?未能等到event,故timeout
#if?DEBUG_POLL_AND_WAKE
????????ALOGD("%p?~?pollOnce?-?timeout",?this);
#endif
????????result?=?ALOOPER_POLL_TIMEOUT;
????????goto?Done;
????}3. 有event發(fā)生:
????//?Handle?all?events.
#if?DEBUG_POLL_AND_WAKE
????ALOGD("%p?~?pollOnce?-?handling?events?from?%d?fds",?this,?eventCount);
#endif
????for?(int?i?=?0;?i?<?eventCount;?i++)?{//有event,則處理
????????int?fd?=?eventItems[i].data.fd;
????????uint32_t?epollEvents?=?eventItems[i].events;
????????if?(fd?==?mWakeReadPipeFd)?{//說(shuō)明java層或者C++層有新的Message
????????????if?(epollEvents?&?EPOLLIN)?{
????????????????awoken();//讀取命名管道內(nèi)的數(shù)據(jù)
????????????}?else?{
????????????????ALOGW("Ignoring?unexpected?epoll?events?0x%x?on?wake?read?pipe.",?epollEvents);
????????????}
????????}?else?{
????????????ssize_t?requestIndex?=?mRequests.indexOfKey(fd);
????????????if?(requestIndex?>=?0)?{
????????????????int?events?=?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));//把event添加到mResponses中,等待后續(xù)處理
????????????}?else?{
????????????????ALOGW("Ignoring?unexpected?epoll?events?0x%x?on?fd?%d?that?is?"
????????????????????????"no?longer?registered.",?epollEvents,?fd);
????????????}
????????}
????}? ? 處理event的時(shí)候,需要分為兩類(lèi):fd==mWakeReadPipeFd和fd!=mWakeReadPipeFd
fd==mWakeReadPipeFd:說(shuō)明C++層,或者java層有新的Message出現(xiàn),需要處理。這種情況下,只需要讀mWakeReadPipeFd內(nèi)的數(shù)據(jù)即可
void?Looper::awoken()?{
#if?DEBUG_POLL_AND_WAKE
????ALOGD("%p?~?awoken",?this);
#endif
????char?buffer[16];
????ssize_t?nRead;
????do?{
????????nRead?=?read(mWakeReadPipeFd,?buffer,?sizeof(buffer));
????}?while?((nRead?==?-1?&&?errno?==?EINTR)?||?nRead?==?sizeof(buffer));
}fd!=mWakeReadPipeFd:首先需要搞明白fd是哪來(lái)的:
????struct?Request?{
????????int?fd;
????????int?ident;
????????spcallback;
????????void*?data;
????};
????struct?Response?{
????????int?events;
????????Request?request;
????};/**
?*?A?looper?callback.
?*/
class?LooperCallback?:?public?virtual?RefBase?{
protected:
????virtual?~LooperCallback()?{?}
public:
????/**
?????*?Handles?a?poll?event?for?the?given?file?descriptor.
?????*?It?is?given?the?file?descriptor?it?is?associated?with,
?????*?a?bitmask?of?the?poll?events?that?were?triggered?(typically?ALOOPER_EVENT_INPUT),
?????*?and?the?data?pointer?that?was?originally?supplied.
?????*
?????*?Implementations?should?return?1?to?continue?receiving?callbacks,?or?0
?????*?to?have?this?file?descriptor?and?callback?unregistered?from?the?looper.
?????*/
????virtual?int?handleEvent(int?fd,?int?events,?void*?data)?=?0;
};int?Looper::addFd(int?fd,?int?ident,?int?events,?const?sp&?callback,?void*?data)?{
#if?DEBUG_CALLBACKS
????ALOGD("%p?~?addFd?-?fd=%d,?ident=%d,?events=0x%x,?callback=%p,?data=%p",?this,?fd,?ident,
????????????events,?callback.get(),?data);
#endif
????if?(!callback.get())?{
????????if?(!?mAllowNonCallbacks)?{
????????????ALOGE("Invalid?attempt?to?set?NULL?callback?but?not?allowed?for?this?looper.");
????????????return?-1;
????????}
????????if?(ident?<?0)?{//僅當(dāng)Looper支持NonCallbacks,并且ident大于0時(shí),允許添加callback為null的Fd
????????????ALOGE("Invalid?attempt?to?set?NULL?callback?with?ident?<?0.");
????????????return?-1;
????????}
????}?else?{
????????ident?=?ALOOPER_POLL_CALLBACK;
????}
????int?epollEvents?=?0;
????if?(events?&?ALOOPER_EVENT_INPUT)?epollEvents?|=?EPOLLIN;
????if?(events?&?ALOOPER_EVENT_OUTPUT)?epollEvents?|=?EPOLLOUT;
????{?//?acquire?lock
????????AutoMutex?_l(mLock);
????????Request?request;
????????request.fd?=?fd;
????????request.ident?=?ident;
????????request.callback?=?callback;
????????request.data?=?data;
????????struct?epoll_event?eventItem;
????????memset(&?eventItem,?0,?sizeof(epoll_event));?//?zero?out?unused?members?of?data?field?union
????????eventItem.events?=?epollEvents;
????????eventItem.data.fd?=?fd;
????????ssize_t?requestIndex?=?mRequests.indexOfKey(fd);
????????if?(requestIndex?<?0)?{
????????????int?epollResult?=?epoll_ctl(mEpollFd,?EPOLL_CTL_ADD,?fd,?&?eventItem);
????????????if?(epollResult?<?0)?{
????????????????ALOGE("Error?adding?epoll?events?for?fd?%d,?errno=%d",?fd,?errno);
????????????????return?-1;
????????????}
????????????mRequests.add(fd,?request);
????????}?else?{//存在則替換
????????????int?epollResult?=?epoll_ctl(mEpollFd,?EPOLL_CTL_MOD,?fd,?&?eventItem);
????????????if?(epollResult?<?0)?{
????????????????ALOGE("Error?modifying?epoll?events?for?fd?%d,?errno=%d",?fd,?errno);
????????????????return?-1;
????????????}
????????????mRequests.replaceValueAt(requestIndex,?request);
????????}
????}?//?release?lock
????return?1;
}? ? 從上面的代碼,我們可知,Looper還支持添加Fd和自定義的callback,類(lèi)似java層的Message.callback。?
? ?通過(guò)addFd函數(shù),可以向Looper的mEpollFd添加指定的Fd,當(dāng)Fd觸發(fā)指定的event .e.i ?EPOLLIN or EPOLLOUT時(shí),指定的相應(yīng)的自定義callback就會(huì)得到執(zhí)行。
? ?另外,當(dāng)Looper支持noncallback時(shí),還可以向Looper添加callback為null的Fd,因?yàn)闆](méi)有callback,所以Fd添加者需要調(diào)用int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) 通過(guò)outFd、outEvent、outData參數(shù)獲取數(shù)據(jù)并進(jìn)行處理。
? ? 所以當(dāng)Fd觸發(fā)消息時(shí),需要生成對(duì)應(yīng)到reponse并添加到meResponses中,等待后續(xù)的處理。
void?Looper::pushResponse(int?events,?const?Request&?request)?{
????Response?response;
????response.events?=?events;
????response.request?=?request;
????mResponses.push(response);
}? ? 到這里為止,epoll_wait函數(shù)返回的三種結(jié)果的不同處理已經(jīng)解析完畢,接下來(lái)代碼進(jìn)入共同的Done環(huán)節(jié)。
處理C++層的Message:
Done:?;
????//?處理C++層的Message
????//?Invoke?pending?message?callbacks.
????mNextMessageUptime?=?LLONG_MAX;
????while?(mMessageEnvelopes.size()?!=?0)?{
????????nsecs_t?now?=?systemTime(SYSTEM_TIME_MONOTONIC);
????????const?MessageEnvelope&?messageEnvelope?=?mMessageEnvelopes.itemAt(0);
????????if?(messageEnvelope.uptime?<=?now)?{
????????????//?Remove?the?envelope?from?the?list.
????????????//?We?keep?a?strong?reference?to?the?handler?until?the?call?to?handleMessage
????????????//?finishes.??Then?we?drop?it?so?that?the?handler?can?be?deleted?*before*
????????????//?we?reacquire?our?lock.
????????????{?//?obtain?handler
????????????????sphandler?=?messageEnvelope.handler;
????????????????Message?message?=?messageEnvelope.message;
????????????????mMessageEnvelopes.removeAt(0);
????????????????mSendingMessage?=?true;
????????????????mLock.unlock();
#if?DEBUG_POLL_AND_WAKE?||?DEBUG_CALLBACKS
????????????????ALOGD("%p?~?pollOnce?-?sending?message:?handler=%p,?what=%d",
????????????????????????this,?handler.get(),?message.what);
#endif
????????????????handler->handleMessage(message);//調(diào)用handler->handleMessage
????????????}?//?release?handler
????????????mLock.lock();
????????????mSendingMessage?=?false;
????????????result?=?ALOOPER_POLL_CALLBACK;
????????}?else?{
????????????//?The?last?message?left?at?the?head?of?the?queue?determines?the?next?wakeup?time.
????????????mNextMessageUptime?=?messageEnvelope.uptime;//更新mNextMessageUptime
????????????break;
????????}
????}處理Response:
????//?處理mResponses
????//?Invoke?all?response?callbacks.
????for?(size_t?i?=?0;?i?<?mResponses.size();?i++)?{
????????Response&?response?=?mResponses.editItemAt(i);
????????if?(response.request.ident?==?ALOOPER_POLL_CALLBACK)?{
????????????int?fd?=?response.request.fd;
????????????int?events?=?response.events;
????????????void*?data?=?response.request.data;
#if?DEBUG_POLL_AND_WAKE?||?DEBUG_CALLBACKS
????????????ALOGD("%p?~?pollOnce?-?invoking?fd?event?callback?%p:?fd=%d,?events=0x%x,?data=%p",
????????????????????this,?response.request.callback.get(),?fd,?events,?data);
#endif
????????????int?callbackResult?=?response.request.callback->handleEvent(fd,?events,?data);//調(diào)用callback->handleEvent
????????????if?(callbackResult?==?0)?{
????????????????removeFd(fd);
????????????}
????????????//?Clear?the?callback?reference?in?the?response?structure?promptly?because?we
????????????//?will?not?clear?the?response?vector?itself?until?the?next?poll.
????????????response.request.callback.clear();
????????????result?=?ALOOPER_POLL_CALLBACK;
????????}
????}? ? 搞懂了上面的代碼,我們就很容易明白wake函數(shù)做了些什么:
void?Looper::wake()?{
#if?DEBUG_POLL_AND_WAKE
????ALOGD("%p?~?wake",?this);
#endif
????ssize_t?nWrite;
????do?{
????????nWrite?=?write(mWakeWritePipeFd,?"W",?1);//向mWakeWritePipeFd中寫(xiě)入一個(gè)字符,所以mWakeReadPipeFd就會(huì)觸發(fā)EPOLLIN?event
????}?while?(nWrite?==?-1?&&?errno?==?EINTR);
????if?(nWrite?!=?1)?{
????????if?(errno?!=?EAGAIN)?{
????????????ALOGW("Could?not?write?wake?signal,?errno=%d",?errno);
????????}
????}
}? ? 小結(jié): Looper通過(guò)epoll函數(shù)組實(shí)現(xiàn)了一個(gè)可以支持隨時(shí)喚醒的阻塞機(jī)制Looper支持兩種不同的方式處理消息:Message + MessageHandler 和 LooperCallback。Looper的阻塞在如下四種條件下會(huì)被喚醒: 發(fā)生錯(cuò)誤等待超時(shí)出現(xiàn)需要處理的新Message(包括C++層和Java層)由addFd函數(shù)添加的Fd觸發(fā)event
?
總結(jié):
在哪個(gè)線程調(diào)用JAVA層的Looper.loop(),Mesage和callback(包括Java層和C++層)就在哪個(gè)線程被處理,上圖為L(zhǎng)ooper.loop函數(shù)的時(shí)序圖。C++層的NativeMesasgeQueue不應(yīng)該是Java層的MesageQueue的內(nèi)部實(shí)現(xiàn),而更接近于“欒生兄弟”的關(guān)系。MessageQueue負(fù)責(zé)處理java層上到消息,NativeMessageQueue負(fù)責(zé)處理C++層上的消息。其中Java層是在android.os.Looper.looper函數(shù)中調(diào)用android.os.Handler.dispatchMessage處理,而C++層是在android::Looper::pollInner函數(shù)中調(diào)用android::MessageHandler::handleMessage & android:LooperCallback::handleEvent函數(shù)處理。NativeMessageQueue利用Looper類(lèi)實(shí)現(xiàn)了一個(gè)基于epoll函數(shù)和文件描述符(Fd)的可喚醒的阻塞機(jī)制。





