直接驱动是Java层消息循环。
java$Looper.loop()循环调用MessageQueue#next()返回一个Message给该Message对象绑定的Java$Handler处理。而正是这个next()方法驱动着Native层的消息循环:next()->nativePollOnce()->NativeMessageQueue::pollOnce->Native$Looper::pollOnce()
在Native$Looper::pollOnce()方法中,调用了epoll_wait(mEpollHandler,eventItems,eventItemsSize,timeoutMillis),这个方法是阻塞的,必须有某个事件发送才会返回,既然这个方法是每次调用next()都会调用到的,所以这个返回的条件必须要宽松点,否则处理一个Java层的消息都要老半天了。那么这个触发epoll_wait返回的事件有:
1.Native层sendMessage到NativeMessageQueue(即调用Native$Looper::sendMessage())
2.通过Native$Looper::addFd(fd,interestedEvent,callback)监听文件fd(添加监听请求),fd发生了Looper感兴趣的事件
3.Java层sendMessage时,Java层的MessageQueue中没有其他消息时,则会向mWakeReadPipe写入一个字符,以唤醒epoll_wait,好让Java层快点处理这个消息(注意,如果此时MessageQueue中有其他消息时则不会去唤醒)
4.监听的fd发生错误
5.超时,即在指定时间内,以上事件都没有发生时。
而从epoll_wait中返回后,并不代表马上从nativePollOnce返回从而去处理Java层中的消息。从epoll_wait中返回后,首先从eventItems这个事件数组中获取发生的事件,则循环逐个处理;如果因mWakeReadPipe唤醒(即上面所说第三种情况),即读取并清空mWakeReadPipe这个fd中的数据;如果是Native$Looper::addFd(fd,interestedEvent,callback)监听的文件fd的事件,则一般把这个fd及事件callback打包好放到一个容器中,在处理完Native中的所有消息后,再处理这些事件。最后就是从nativePollOnce中返回了。所以可以看出,优先级处理顺序是Native Message->对Native$Looper::addFd发生的事件的callback调用->Java Message
所以在代码流程上看,Java Looper和Native Looper像是外循环和内循环的关系,但在业务逻辑上看,Java Looper和Native Looper像是平行关系,各自有各自的一个消息队列。