Android中Java层和Native层的消息循环机制

本文深入解析了Java层消息循环(Looper.loop)与Native层消息循环的交互机制,阐述了MessageQueue如何通过next()方法驱动Native层,以及epoll_wait在事件监听中的作用。详细介绍了事件触发条件,包括Native层消息发送、文件描述符事件、Java层消息唤醒等,揭示了Native与Java层消息处理的优先级和流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接驱动是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像是平行关系,各自有各自的一个消息队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值