Android应用程序消息处理机制(Looper、Handler)分析(8)

移动开发 Android
执行完这些IdleHandler之后,线程下次调用nativePollOnce函数时,就不设置超时时间了,因为,很有可能在执行IdleHandler的时候,已经有新的消息加入到消息队列中去了。

执行完这些IdleHandler之后,线程下次调用nativePollOnce函数时,就不设置超时时间了。

因为,很有可能在执行IdleHandler的时候,已经有新的消息加入到消息队列中去了。

正因为如此,

要重置nextPollTimeoutMillis的值:

  1. [java] view plaincopy// While calling an idle handler, a new message could 
  2. ve been delivered 
  3. // so go back and look again for a pending message without waiting. 
  4. nextPollTimeoutMillis = 0

分析完MessageQueue的这个next函数之后,我们就要深入分析一下JNI方法nativePollOnce了,看看它是如何进入等待状态的, 这个函数定义在frameworks/base/core/jni/android_os_MessageQueue.cpp文件中:

  1.   [cpp] view plaincopystatic void 
  2. android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, 
  3.   jint ptr, jint timeoutMillis) { 
  4.   NativeMessageQueue* nativeMessageQueue = 
  5. reinterpret_cast(ptr); 
  6.   nativeMessageQueue->pollOnce(timeoutMillis); 
  7.   } 

这个函数首先是通过传进入的参数ptr取回前面在Java层创建MessageQueue对象时在JNI层创建的NatvieMessageQueue对象,然后调用它的pollOnce函数:

  1. [cpp] view plaincopyvoid NativeMessageQueue::pollOnce(int timeoutMillis) 
  2.  
  3.  mLooper->pollOnce(timeoutMillis); 
  4.  } 

这里将操作转发给mLooper对象的pollOnce函数处理,这里的mLooper对象是在C++层的对象,它也是在前面在JNI层创建的 NatvieMessageQueue对象时创建的,它的pollOnce函数定义在frameworks/base/libs/utils /Looper.cpp文件中:

  1. [cpp] view plaincopyint Looper::pollOnce(int timeoutMillis, int* outFd, 
  2. t* outEvents, void** outData) { 
  3. int result = 0
  4. for (;;) { 
  5. ...... 
  6. if (result != 0) { 
  7. ...... 
  8. return result; 
  9. result = pollInner(timeoutMillis); 

为了方便讨论,我们把这个函数的无关部分都去掉,它主要就是调用pollInner函数来进一步操作,如果pollInner返回值不等于0,这个函数就可以返回了。

函数pollInner的定义如下:

  1. [cpp] view plaincopyint Looper::pollInner(int timeoutMillis) { 
  2. ...... 
  3. int result = ALOOPER_POLL_WAKE; 
  4. ...... 
  5. #ifdef LOOPER_USES_EPOLL 
  6. struct epoll_event eventItems[EPOLL_MAX_EVENTS]; 
  7. int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, 
  8. meoutMillis); 
  9. bool acquiredLock = false
  10. #else 
  11. ...... 
  12. #endif 
  13. if (eventCount < 0) { 
  14. if (errno == EINTR) { 
  15. goto Done; 
  16. LOGW("Poll failed with an unexpected error, errno=%d", errno); 
  17. result = ALOOPER_POLL_ERROR; 
  18. goto Done; 
  19. if (eventCount == 0) { 
  20. ...... 
  21. result = ALOOPER_POLL_TIMEOUT; 
  22. goto Done; 
  23. ...... 
  24. #ifdef LOOPER_USES_EPOLL 
  25. for (int i = 0; i < eventCount; i++) { 
  26. int fd = eventItems[i].data.fd; 
  27. uint32_t epollEvents = eventItems[i].events; 
  28. if (fd == mWakeReadPipeFd) { 
  29. if (epollEvents & EPOLLIN) { 
  30. awoken(); 
  31. else { 
  32. LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe."
  33. ollEvents); 
  34. else { 
  35. ...... 
  36. if (acquiredLock) { 
  37. mLock.unlock(); 
  38. Done: ; 
  39. #else 
  40. ...... 
  41. #endif 
  42. ...... 
  43. return result; 

 

责任编辑:闫佳明 来源: bbs.9ria
相关推荐

2014-05-22 15:45:58

Android消息处理机制Looper

2014-05-22 15:15:53

Android消息处理机制Looper

2014-05-22 15:33:31

Android消息处理机制Looper

2014-05-22 15:18:25

Android消息处理机制Looper

2014-05-22 14:57:28

Android消息处理机制Looper

2014-05-22 15:48:50

Android消息处理机制Looper

2014-05-22 15:41:59

Android消息处理机制Looper

2014-05-22 15:07:44

Android消息处理机制Looper

2014-05-22 15:04:00

Android消息处理机制Looper

2014-05-22 15:00:16

Android消息处理机制Looper

2011-04-28 11:01:40

Android消息处理LooperHandler

2011-11-23 09:33:45

HandlerLooperMessage

2014-05-27 10:13:57

移动技术半月刊

2016-10-21 13:03:18

androidhandlerlooper

2011-09-05 17:40:40

MTK定时器

2011-03-17 09:20:05

异常处理机制

2021-08-12 16:28:10

AndroidHandleLooper

2023-03-08 08:54:59

SpringMVCJava

2023-06-15 14:09:00

解析器Servlet容器

2011-07-01 14:20:59

Qt 事件
点赞
收藏

51CTO技术栈公众号