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

當(dāng)前位置:首頁 > > 充電吧
[導(dǎo)讀]? ? 接著上一篇文章Android消息機(jī)制不完全解析(上),接著看C++部分的實(shí)現(xiàn)。? ? 首先,看看在/frameworks/base/core/jni/android_os_MessageQue

? ? 接著上一篇文章Android消息機(jī)制不完全解析(上),接著看C++部分的實(shí)現(xiàn)。


? ? 首先,看看在/frameworks/base/core/jni/android_os_MessageQueue.cpp文件中看看android.os.MessageQueue類中的四個(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類。不過,在開始解析NativeMessageQueue之前,我們再看一些有意思的代碼:


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類型并保存到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語言沒有指針的說法,但是,這里的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:銷毀NativeMessageQeue實(shí)例NativeMessageQueue
? ? 先來看看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)簡單,交給mLooper的同名函數(shù)。


Looper


? ? 先來看看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)被我精簡了大部分,現(xiàn)在我們只關(guān)注我們關(guān)心的:pollonce和wake函數(shù)。


? ? 還是從構(gòu)造函數(shù)開始(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);
????//?開始使用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)聽隊(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í)無視
???????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)!
????}
}

? ? 接著往下看,代碼有些長,但請仔細(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;

????//?開始輪詢
????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;
}

? ? 代碼比較長,所以分段分析:

????//?設(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
}

? ? 是不是覺得上面的代碼似曾相識(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;
????//?開始輪詢
????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ò)、沒有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. 沒有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)?{//說明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í)候,需要分為兩類:fd==mWakeReadPipeFd和fd!=mWakeReadPipeFd

fd==mWakeReadPipeFd:說明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是哪來的:


????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,類似java層的Message.callback。?

? ?通過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)闆]有callback,所以Fd添加者需要調(diào)用int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) 通過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)解析完畢,接下來代碼進(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中寫入一個(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通過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è)線程被處理,上圖為Looper.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類實(shí)現(xiàn)了一個(gè)基于epoll函數(shù)和文件描述符(Fd)的可喚醒的阻塞機(jī)制。

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

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉