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

管道是Linux系统中的一种进程间通信机制,具体可以参考前面一篇文章Android学习启动篇推荐的一本书《Linux内核源代码情景分析》中的第6 章--传统的Uinx进程间通信。

创新互联建站10多年成都定制网页设计服务;为您提供网站建设,网站制作,网页设计及高端网站定制服务,成都定制网页设计及推广,对水泥搅拌车等多个方面拥有多年设计经验的网站建设公司。

简单来说,管道就是一个文件,在管道的两端,分别是两个打开文件文件描述符,这两个打开文件描述符都是对应同一个文件, 其中一个是用来读的,别一个是用来写的,一般的使用方式就是,一个线程通过读文件描述符中来读管道的内容,当管道没有内容时,这个线程就会进入等待状态, 而另外一个线程通过写文件描述符来向管道中写入内容,写入内容的时候,如果另一端正有线程正在等待管道中的内容,那么这个线程就会被唤醒。

这个等待和唤醒 的操作是如何进行的呢,这就要借助Linux系统中的epoll机制了。

Linux系统中的epoll机制为处理大批量句柄而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著减 少程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。

但是这里我们其实只需要监控的IO接口只有mWakeReadPipeFd一个,即前面我们所创建的管道的读端,为什么还需要用到epoll呢?有点用牛刀来杀鸡的味道。

其实不然,这个looper类是非常强大的,它除了监控内部所创建的管 道接口之外,还提供了addFd接口供外界面调用,外界可以通过这个接口把自己想要监控的IO事件一并加入到这个Looper对象中去,当所有这些被监控 的IO接口上面有事件发生时,就会唤醒相应的线程来处理,不过这里我们只关心刚才所创建的管道的IO事件的发生。

我们再回到NativeMessageQueue的构造函数中,看看JNI层的Looper对象的创建过程,即看看它的构造函数是如何实现的,这个Looper类实现在frameworks/base/libs/utils/Looper.cpp文件中:

 
 
  1. [cpp] view plaincopyLooper::Looper(bool allowNonCallbacks) : 
  2. mAllowNonCallbacks(allowNonCallbacks), 
  3. mResponseIndex(0) { 
  4. int wakeFds[2]; 
  5. int result = pipe(wakeFds); 
  6. ...... 
  7. mWakeReadPipeFd = wakeFds[0]; 
  8. mWakeWritePipeFd = wakeFds[1]; 
  9. ...... 
  10. #ifdef LOOPER_USES_EPOLL 
  11. // Allocate the epoll instance and register the wake pipe. 
  12. mEpollFd = epoll_create(EPOLL_SIZE_HINT); 
  13. ...... 
  14. struct epoll_event eventItem; 
  15. memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members 
  16.  data field union 
  17. eventItem.events = EPOLLIN; 
  18. eventItem.data.fd = mWakeReadPipeFd; 
  19. result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & 
  20. entItem); 
  21. ...... 
  22. #else 
  23. ...... 
  24. #endif 
  25. ...... 

这个构造函数做的事情非常重要,它跟我们后面要介绍的应用程序主线程在消息队列中没有消息时要进入等待状态以及当消息队列有消息时要把应用程序主线程唤醒的这两个知识点息息相关。它主要就是通过pipe系统调用来创建了一个管道了:

 
 
  1. [cpp] view plaincopyint wakeFds[2]; 
  2.  int result = pipe(wakeFds); 
  3.  ...... 
  4.  mWakeReadPipeFd = wakeFds[0]; 
  5.  mWakeWritePipeFd = wakeFds[1];

要使用Linux系统的epoll机制,首先要通过epoll_create来创建一个epoll专用的文件描述符:

 
 
  1. [cpp] view plaincopymEpollFd = epoll_create(EPOLL_SIZE_HINT); 

传入的参数EPOLL_SIZE_HINT是在这个mEpollFd上能监控的***文件描述符数。

分享名称:Android应用程序消息处理机制(Looper、Handler)分析(4)
网页链接:http://www.zyruijie.cn/qtweb/news7/7357.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联