外观
Handler 导致的内存泄漏是如何发生的?如何使用 WeakReference 避免?
标准回答
典型引用链是 MessageQueue → Message/Runnable → Handler 或闭包 → Activity。可以用静态 Handler 配合 WeakReference 读取页面,但更关键的是在适当生命周期移除未执行消息、取消任务,且 Runnable 本身也不能再次强引用页面。
通俗例子
发出一分钟后执行的消息,十秒后关闭页面;剩下五十秒内,任务可能仍引用页面。清理无用消息,弱引用取出后还要判空和检查状态。
深入解释
**为什么延迟消息会留住页面:**尚未执行的 Message 或 Runnable 留在 MessageQueue 中,回调对象可能再指向 Handler 或 Activity,所以页面关闭后仍有一条可达路径。
**弱引用有什么边界:**WeakReference 不阻止回收,但回调执行时对象可能已经消失,也可能虽然存在却不再适合更新。仍要判空、核对生命周期,并移除不需要的任务。
示例代码
java
private final Handler main = new Handler(Looper.getMainLooper());
private final Runnable refresh = this::refreshUi;
@Override protected void onDestroy() {
main.removeCallbacks(refresh);
super.onDestroy();
}易混淆点
WeakReference 不会取消任务,也不会自动避免所有其他强引用。
内容来源
- Android · AI Agent 知识手册 · 原条目
3.2.2