You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android中Message对象的回收时机及复用问题咨询

关于Android Message回收与复用的问题解答

兄弟,这个问题我之前做项目的时候踩过坑,刚好能给你把Android Message的回收逻辑讲得明明白白,帮你避开那些诡异的bug!

一、系统何时调用Message的recycle()方法?

其实咱们平时很少直接接触recycle()方法,因为Android内部用的是包私有方法recycleUnchecked()来做回收。当Message走完它的生命周期,系统会自动把它丢回全局的Message对象池:

  • 当Handler的handleMessage()执行完之后,MessageQueue在next()方法里会自动调用recycleUnchecked(),把这个Message放回池子里等着复用;
  • 如果你主动调用Handler.removeMessages()Handler.removeCallbacksAndMessages()这类方法移除还没处理的Message,这些消息会立刻被回收;
  • 要是关联的Looper退出了(比如主线程退出或者子线程Looper quit),MessageQueue里剩下的所有未处理Message会被批量回收掉。

二、能不能在目标Handler中复用同一个Message对象?

绝对不行! 这就是你遇到“Message内容自行变更”的核心原因!

一旦Message被回收,它就会回到对象池,后续任何地方调用Message.obtain()都可能拿到这个Message,用来装其他请求的内容。如果你在Handler里还攥着这个Message的引用,要么你修改它的时候会污染其他请求的消息,要么其他请求修改这个复用的Message时,你手里的引用会看到莫名其妙的内容变化,这种bug排查起来巨头疼!

正确的姿势是:每次发消息就用Message.obtain()从池里拿一个,处理完就彻底放手,别留任何引用,让系统自己管回收复用的事儿。

三、Message何时会被系统回收?

把回收时机再给你总结一遍,一目了然:

  • 已经被Handler处理完的Message,handleMessage()一结束就会被回收;
  • 被主动移除的未处理Message,调用移除方法后立刻回收;
  • 关联的Looper退出时,队列里剩下的所有未处理Message会被批量回收;
  • 补充一句:如果Message正处于“被使用”状态(比如正在MessageQueue里排队或者正在被处理),系统不会碰它,只有等它的使用状态解除后才会进入回收流程。

内容的提问来源于stack exchange,提问作者jkv

火山引擎 最新活动