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




