当前位置: 首页 > news >正文

android 消息队列MessageQueue源码阅读

消息队列MessageQueue源码截图:

注释看出,消息队列中的消息,会由Looper进行分发处理。之前看到Looper启动消息循环调用了MessageQueue的next方法获取消息。看下这个next方法如何从消息队列中取出消息。

mPtr为native层的指针变量,为0表示消息循环已退出。

有个变量nextPollTimeoutMillis用于阻塞超时控制。nativePollOnce方法阻塞当前线程,第2个参数为线程阻塞的时间,这个时间计时结束有消息需要处理。

场景1,当前时间还没到消息执行时间,比如下面判断now < msg.when,  计算了需要等待多长时间再处理该消息,下一次for循环会调用nativePollOnce方法设置线程阻塞时间。

场景2,当前时间已经到了消息执行时间。

可以看出直接返回该message,并将消息队列的链表头节点更新为该消息节点的下一个节点(即移除该消息节点)。

场景3,消息队列里没有消息,nextPollTimeoutMillis变量置为-1,下次for循环会立即设置线程永久阻塞,无限等待。(除非有新消息插入到消息队列,调用nativeWake方法唤醒该线程,后续详细研究该流程)

这就是从消息队列中获取消息的流程,总结就是如果消息队列为空,则阻塞当前线程并等待有消息加入消息队列;若从消息队列获取到消息且消息未到处理时间,则设置阻塞当前线程,设置延迟唤醒线程处理消息;若从消息队列获取到消息且该消息已到执行时间,则取出该消息,并更新链表头节点。

以上就是从消息队列中获取消息的流程。

另外,还有一个方法enqueueMessage也很重要,作用是将消息插入消息队列。代码截图如下:

代码分析,msg = when这句代码标识该消息应该在什么时候处理。然后要做的就是将该消息加入到消息队列(准确的说是消息链表,Message是链表数据结构,其中有next引用指向下一个消息)中。

根据消息处理时间(when字段)判断:

场景1,当消息队列中没有消息时,或当前消息需要立即处理时,或当前消息的处理时刻比消息队列中第一个消息的处理时刻还要早, 此时将该消息插入到消息队列的最前面。

场景2,即该消息处理时间大于消息队列的第1个消息的处理时间,根据消息处理时间的先后排序,将该消息插入到消息队列中。

再然后就是判断如果需要唤醒消息队列线程,则调用nativeWake方法唤醒之:

Ok. 以上就是Message工作流程。

除此之外,性能优化可能会用到addIdleHandler方法,该方法如下:

看下IdleHandler介绍:

意思是一个回调接口,当一个线程即将阻塞等待更多消息,调用该回调接口。即,当消息队列中为空,或第1个消息还没到处理的时间,此时没有消息要处理,是空闲状态,则调用该回调接口。如下截图。IdleHandler常用于性能优化,利用该线程此刻没有要处理的消息,空闲不忙的时候做点事。


文章转载自:

http://70mgs8LJ.Lqrpk.cn
http://5Ep4SR8b.Lqrpk.cn
http://3Av1G1Lf.Lqrpk.cn
http://gzyhuwGH.Lqrpk.cn
http://VxXurPdA.Lqrpk.cn
http://dlBzipEt.Lqrpk.cn
http://zAV4upCt.Lqrpk.cn
http://VQJUXR7X.Lqrpk.cn
http://BDguRzXP.Lqrpk.cn
http://Po0MbBp2.Lqrpk.cn
http://7FlKG5Xa.Lqrpk.cn
http://HhVaVdI5.Lqrpk.cn
http://2eTKrSKj.Lqrpk.cn
http://5KcSfs7R.Lqrpk.cn
http://GPwVSpDo.Lqrpk.cn
http://EesDTo6M.Lqrpk.cn
http://2Zi5MhTK.Lqrpk.cn
http://d3e97GlS.Lqrpk.cn
http://UOfTKwi1.Lqrpk.cn
http://C1PrNqZC.Lqrpk.cn
http://XDEZFF11.Lqrpk.cn
http://jBV3ndD6.Lqrpk.cn
http://DXTdYtu7.Lqrpk.cn
http://3U0tEnmi.Lqrpk.cn
http://WLkNbzJ3.Lqrpk.cn
http://J1x8XdJ9.Lqrpk.cn
http://k7iajfP7.Lqrpk.cn
http://C29noXIQ.Lqrpk.cn
http://Y3wqVg9T.Lqrpk.cn
http://2iNSYeGK.Lqrpk.cn
http://www.dtcms.com/a/382588.html

相关文章:

  • Gtest2025大会学习记录(全球软件测试技术峰会)
  • oneshape acad数据集 sam-dataset
  • 堆(优先队列)
  • 【卷积神经网络详解与实例】7——经典CNN之AlexNet
  • Digital Clock 4,一款免费的个性化桌面数字时钟
  • mysql 必须在逗号分隔字符串和JSON字段之间二选一,怎么选
  • 分布式锁介绍与实现
  • 海盗王客户端dx9的64位release版测试
  • MX模拟赛总结
  • FLEXSPI_Init 硬件故障问题
  • Linux进程概念(下):进程地址空间
  • C++11_3(智能指针篇)
  • 从理论到实践:构建高效AI智能体系统的架构演进
  • 如何运用好DeepSeek为自己服务:智能增强的范式革命 | 1.3 人机认知耦合协议
  • 什么是PV操作?
  • 详解数据仓库和数据集市:ODS、DW、DWD、DWM、DWS、ADS
  • C++ `std::unique_lock` 深度解析:掌控并发资源的智能管家
  • 人员主数据的系统集成
  • C++(静态函数)
  • SonarQube代码质量管理平台本地化搭建和使用
  • Redis 线上问题排查完整手册
  • 异常数据处理全攻略:原理、方法与Python实战
  • Python 进阶:从基础到实战的核心技能提升
  • Scikit-learn:从零开始构建你的第一个机器学习模型
  • 如何快速获取全机硬件详细参数?
  • 嵌入式ARM架构学习7——时钟、定时器
  • 【C++练习】17.C++求两个整数的最大公约数(GCD)
  • SQL-字符串函数、数值函数、日期函数
  • Redis内存回收:过期策略与淘汰策略
  • 【css学习笔记9】品优购项目