这里,首先是调用epoll_wait函数来看看epoll专用文件描述符mEpollFd所监控的文件描述符是否有IO事件发生,它设置监控的超时时间为timeoutMillis:
创新互联主营洛阳网站建设的网络公司,主营网站建设方案,成都app软件开发公司,洛阳h5微信小程序搭建,洛阳网站营销推广欢迎洛阳等地区企业咨询
- [cpp] view plaincopyint eventCount = epoll_wait(mEpollFd, eventItems,
- EPOLL_MAX_EVENTS, timeoutMillis);
回忆一下前面的looper的构造函数,我们在里面设置了要监控mWakeReadPipeFd文件描述符的EPOLLIN事件。
当mEpollFd所监控的文件描述符发生了要监控的IO事件后或者监控时间超时后,线程就从epoll_wait返回了,否则线程就会在epoll_wait函数中进入睡眠状态了。
返回后如果eventCount等于0,就说明是超时了:
- [cpp] view plaincopyif (eventCount == 0) {
- ......
- result = ALOOPER_POLL_TIMEOUT;
- goto Done;
- }
如果eventCount不等于0,就说明发生要监控的事件:
- [cpp] view plaincopyfor (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.",
- epollEvents);
- }
- } else {
- ......
- }
- }
这里我们只关注mWakeReadPipeFd文件描述符上的事件,如果在mWakeReadPipeFd文件描述符上发生了EPOLLIN就说明应用程 序中的消息队列里面有新的消息需要处理了,接下来它就会先调用awoken函数清空管道中把内容,以便下次再调用pollInner函数时,知道自从上次 处理完消息队列中的消息后,有没有新的消息加进来。
函数awoken的实现很简单,它只是把管道中的内容都读取出来:
- [cpp] view plaincopyvoid Looper::awoken() {
- ......
- char buffer[16];
- ssize_t nRead;
- do {
- nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
- } while ((nRead == -1 && errno == EINTR) || nRead ==
- zeof(buffer));
- }
因为当其它的线程向应用程序的消息队列加入新的消息时,会向这个管道写入新的内容来通知应用程序主线程有新的消息需要处理了,下面我们分析消息的发送的时候将会看到。
这样,消息的循环过程就分析完了,这部分逻辑还是比较复杂的,它利用Linux系统中的管道(pipe)进程间通信机制来实现消息的等待和处理,不过,了解了这部分内容之后,下面我们分析消息的发送和处理就简单多了。
网站标题:Android应用程序消息处理机制(Looper、Handler)分析(9)
文章位置:http://www.shufengxianlan.com/qtweb/news49/169099.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联