执行完这些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 plaincopystaticvoid
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(inttimeoutMillis)
mLooper->pollOnce(timeoutMillis);
}
这里将操作转发给mLooper对象的pollOnce函数处理,这里的mLooper对象是在C++层的对象,它也是在前面在JNI层创建的 NatvieMessageQueue对象时创建的,它的pollOnce函数定义在frameworks/base/libs/utils /Looper.cpp文件中:
[cpp] view plaincopyint Looper::pollOnce(inttimeoutMillis,int* outFd,
t* outEvents, void** outData) {
intresult =0;
for(;;) {
......
if(result !=0) {
......
returnresult;
}
result = pollInner(timeoutMillis);
}
}
为了方便讨论,我们把这个函数的无关部分都去掉,它主要就是调用pollInner函数来进一步操作,如果pollInner返回值不等于0,这个函数就可以返回了。
函数pollInner的定义如下:
[cpp] view plaincopyint Looper::pollInner(inttimeoutMillis) {
......
intresult = ALOOPER_POLL_WAKE;
......
#ifdef LOOPER_USES_EPOLL
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
inteventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS,
meoutMillis);
bool acquiredLock = false;
#else
......
#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) {
......
result = ALOOPER_POLL_TIMEOUT;
gotoDone;
}
......
#ifdef LOOPER_USES_EPOLL
for(inti =0; i
intfd = 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
......
returnresult;
}
【编辑推荐】
【责任编辑:闫佳明 TEL:(010)68476606】
点赞 0