Handler
sendMessage
的message
保存在哪?
保存在MessageQueue
的Message mMessages
成员变量中,通过message
中的next
维护一个单向链表。message
本身一直在java层,和native
的message没有直接操作关系。looper
分发的消息都是通过messagequeue.mMessages
间接获取的。当sendMessage
时,进入messagequeue
的enqueueMessage
方法,
|
|
接受消息在messagequeue.next()
中,nativePollOnce(ptr, nextPollTimeoutMillis);
方法是陷入到native
层,一般nextPollTimeoutMillis
都为0,说明要马上处理message
,就会执行下面的语句。当没有消息时,nextPollTimeoutMillis
为-1,表示无限阻塞,直到mEpollFd所监控的文件描述符发生了要监控的IO事件后或者监控时间超时后,线程就从epoll_wait返回了,也就会执行下面的操作,说明有新的message可以处理了。也就是说没消息的阻塞是在nativePollOnce
实现的(具体是在native looper ::pollInner),但是这个阻塞不是忙等待,而是闲等待,让出CPU时间。
A. Android应用程序的消息处理机制由消息循环、消息发送和消息处理三个部分组成的。
B. Android应用程序的主线程在进入消息循环过程前,会在内部创建一个Linux管道(Pipe),这个管道的作用是使得Android应用程序主线程在消息队列为空时可以进入空闲等待状态,并且使得当应用程序的消息队列有消息需要处理时唤醒应用程序的主线程。
C. Android应用程序的主线程进入空闲等待状态的方式实际上就是在管道的读端等待管道中有新的内容可读,具体来说就是是通过Linux系统的Epoll机制中的epoll_wait函数进行的。
D. 当往Android应用程序的消息队列中加入新的消息时,会同时往管道中的写端写入内容,通过这种方式就可以唤醒正在等待消息到来的应用程序主线程。
E. 当应用程序主线程在进入空闲等待前,会认为当前线程处理空闲状态,于是就会调用那些已经注册了的IdleHandler接口,使得应用程序有机会在空闲的时候处理一些事情。
—->Android应用程序消息处理机制(Looper、Handler)分析