Handler内存泄漏

会使用Handler之后如何完美的使用Handler成了我们考虑的重点

内存泄漏

JVM的垃圾回收机制相信很多人有所了解,确定一个对象是不是垃圾主要有两种方式:

  • 引用计数法:判断是否有引用指向该对象(难以解决两个垃圾对象循环依赖的问题)
  • 可达性分析:通过遍历Roots集合,判断对象是否有用

内存泄漏指的是一个对象已经不在使用需要GC回收,但是有一个活跃对象持有该对象的引用导致GC无法回收该对象

Handler引用关系

Handler  ->  OutClass

class MainActivity {
    private Handler handler = new Handler() {
        @override
        public void handleMessage(Message msg) { //dosomethine }
    }
}

这种匿名内部类的方式创建的handler对象会持有外部类的引用,只有静态内部类默认不会持有外部类引用

未处理\正在处理的Message  ->  Handler

还记得消息分发是根据什么来的吗?Message有一个属性target,分发消息时调用msg.target.dispatchMessage(msg)方法,而这个target属性就是Handler,所以Handler中没有处理的消息会持有Handler的引用

最终引用关系:未处理\正在处理的Message -> Handler -> OutClass

Handler的内存泄漏

原因:1.存在上述引用关系 2.OutClass生命周期 < Handler

解决:破坏其中一个条件即可

破坏引用关系:静态内部类 + 弱引用

class MainActivity {
    private Handler handler = new MyHandler(this);


    static class MyHandler extends Handler {

        private WeekReference<Activity> reference;

        public MyHandler(Activity activity) {
            使用弱引用持有外部类实例
            reference = new WeakReference<Activity>(activity);
        }

        @Override
        public void handleMessage(msg) { ... }
    }
}

现在的引用关系是怎样的呢?

未处理\正在处理的Message  ->  Handler  ···>  OutClass

弱引用的对象生命周期非常短,只要发生垃圾回收该对象就会被回收,不存在内存泄漏

当外部类销毁时清空Handler内的消息

class MainActivity {
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(msg) { ... }
    }

    @Override
    protected void onDestory() {
        super.onDestory();
        外部类被销毁时,清空Handler中所有消息
        handler.removeCallbacksAndMessages(null);
    }
}

此时引用关系:  Handler  ->  OutClass

为了防止消息未处理的情况,建议使用静态内部类 + 弱引用的方式避免Handler的内存泄漏

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有 朝一 日

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值