执行完这些IdleHandler之后,线程下次调用nativePollOnce函数时,就不设置超时时间了。
因为,很有可能在执行IdleHandler的时候,已经有新的消息加入到消息队列中去了。
正因为如此,
要重置nextPollTimeoutMillis的值:
- [java] view plaincopy// While calling an idle handler, a new message could
- ve been delivered
- // so go back and look again for a pending message without waiting.
- nextPollTimeoutMillis = 0;
分析完MessageQueue的这个next函数之后,我们就要深入分析一下JNI方法nativePollOnce了,看看它是如何进入等待状态的, 这个函数定义在frameworks/base/core/jni/android_os_MessageQueue.cpp文件中:
- [cpp] view plaincopystatic void
- android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
- jint ptr, jint timeoutMillis) {
- NativeMessageQueue* nativeMessageQueue =
- reinterpret_cast(ptr);
- nativeMessageQueue->pollOnce(timeoutMillis);
- }
这个函数首先是通过传进入的参数ptr取回前面在Java层创建MessageQueue对象时在JNI层创建的NatvieMessageQueue对象,然后调用它的pollOnce函数:
- [cpp] view plaincopyvoid NativeMessageQueue::pollOnce(int timeoutMillis)
- mLooper->pollOnce(timeoutMillis);
- }
这里将操作转发给mLooper对象的pollOnce函数处理,这里的mLooper对象是在C++层的对象,它也是在前面在JNI层创建的 NatvieMessageQueue对象时创建的,它的pollOnce函数定义在frameworks/base/libs/utils /Looper.cpp文件中:
- [cpp] view plaincopyint Looper::pollOnce(int timeoutMillis, int* outFd,
- t* outEvents, void** outData) {
- int result = 0;
- for (;;) {
- ......
- if (result != 0) {
- ......
- return result;
- }
- result = pollInner(timeoutMillis);
- }
- }
为了方便讨论,我们把这个函数的无关部分都去掉,它主要就是调用pollInner函数来进一步操作,如果pollInner返回值不等于0,这个函数就可以返回了。
函数pollInner的定义如下:
- [cpp] view plaincopyint Looper::pollInner(int timeoutMillis) {
- ......
- int result = ALOOPER_POLL_WAKE;
- ......
- #ifdef LOOPER_USES_EPOLL
- struct epoll_event eventItems[EPOLL_MAX_EVENTS];
- int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS,
- meoutMillis);
- bool acquiredLock = false;
- #else
- ......
- #endif
- if (eventCount < 0) {
- if (errno == EINTR) {
- goto Done;
- }
- LOGW("Poll failed with an unexpected error, errno=%d", errno);
- result = ALOOPER_POLL_ERROR;
- goto Done;
- }
- if (eventCount == 0) {
- ......
- result = ALOOPER_POLL_TIMEOUT;
- goto Done;
- }
- ......
- #ifdef LOOPER_USES_EPOLL
- for (int i = 0; i < eventCount; i++) {
- int fd = eventItems[i].data.fd;
- uint32_t epollEvents = eventItems[i].events;
- if (fd == mWakeReadPipeFd) {
- if (epollEvents & EPOLLIN) {
- awoken();
- } else {
- LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.",
- ollEvents);
- }
- } else {
- ......
- }
- }
- if (acquiredLock) {
- mLock.unlock();
- }
- Done: ;
- #else
- ......
- #endif
- ......
- return result;
- }