新聞中心
這里,首先是調用epoll_wait函數來看看epoll專用文件描述符mEpollFd所監(jiān)控的文件描述符是否有IO事件發(fā)生,它設置監(jiān)控的超時時間為timeoutMillis:

創(chuàng)新互聯(lián)主營洛陽網站建設的網絡公司,主營網站建設方案,成都app軟件開發(fā)公司,洛陽h5微信小程序搭建,洛陽網站營銷推廣歡迎洛陽等地區(qū)企業(yè)咨詢
- [cpp] view plaincopyint eventCount = epoll_wait(mEpollFd, eventItems,
- EPOLL_MAX_EVENTS, timeoutMillis);
回憶一下前面的looper的構造函數,我們在里面設置了要監(jiān)控mWakeReadPipeFd文件描述符的EPOLLIN事件。
當mEpollFd所監(jiān)控的文件描述符發(fā)生了要監(jiān)控的IO事件后或者監(jiān)控時間超時后,線程就從epoll_wait返回了,否則線程就會在epoll_wait函數中進入睡眠狀態(tài)了。
返回后如果eventCount等于0,就說明是超時了:
- [cpp] view plaincopyif (eventCount == 0) {
- ......
- result = ALOOPER_POLL_TIMEOUT;
- goto Done;
- }
如果eventCount不等于0,就說明發(fā)生要監(jiān)控的事件:
- [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文件描述符上發(fā)生了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));
- }
因為當其它的線程向應用程序的消息隊列加入新的消息時,會向這個管道寫入新的內容來通知應用程序主線程有新的消息需要處理了,下面我們分析消息的發(fā)送的時候將會看到。
這樣,消息的循環(huán)過程就分析完了,這部分邏輯還是比較復雜的,它利用Linux系統(tǒng)中的管道(pipe)進程間通信機制來實現消息的等待和處理,不過,了解了這部分內容之后,下面我們分析消息的發(fā)送和處理就簡單多了。
網站欄目:Android應用程序消息處理機制(Looper、Handler)分析(9)
標題URL:http://www.dlmjj.cn/article/djoehpj.html


咨詢
建站咨詢
