Android Handler、非静态、匿名内部类的内存泄漏,用静态内部类+弱引用或handler.removeCallbackAndMessages(null)解决

44 篇文章 0 订阅

借鉴自:https://www.jianshu.com/p/63aead89f3b9


为啥要用内部类呢,很方便,可以直接访问外部类的东西。所以,非静态、匿名内部类会隐式持有外部类的引用。但是,仅仅持有引用并不会引起内存泄漏,但是如果有什么延时的操作,而且进行某个延时操作的对象还必须以持有外部类为基础才能进行的,这个时候就内存泄漏了。静态内部类可以解决这个问题,后面讲。


比如Handler,里面的message,仍然在消息队列中,而且是延时比如10分钟,这个时候这个Activity的内存泄漏就会维持10分钟以上。为什么呢,因为message的target就是handler,也就是message会持有handler的引用,而handler又持有activity的引用,所以,不光handler也释放不了,activity也释放不了了。(即使你在onDestory里让handler=null 也不行)


解决方式:静态内部类+弱引用。首先介绍下静态内部类。静态内部类,其实可以脱离外部类了,他们是没有联系的。可以称之为,静态嵌套类。只是为了封装或者什么原因,放在你这里罢了,他是一个独立的类。所以就不会隐式持有外部类的引用。但是你又必须得到这个引用,怎么办。采用弱引用即可,写一个Handler的静态方类,然后构造方法里 接受activity的实例,把它维护成弱引用即可。下面是改写后的Handler。

private final MyHandler mHandler = new MyHandler(this);

private static class MyHandler extends Handler {
    private final WeakReference<SampleActivity> mActivity;

    public MyHandler(SampleActivity activity) {
        mActivity = new WeakReference<SampleActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        SampleActivity activity = mActivity.get();
        if (activity != null) {
            // ...
        }
    }
}

private static final Runnable sRunnable = new Runnable() {
    @Override
    public void run() { /* ... */ }
};

其实。。。如果非要用语法糖(匿名内部类)也可以,在Activity的onDestory()中调用handler.removeCallbackAndMessages(null),即可,如果是Thread,则中断线程即可, 总之你要想办法中断。(消息队列分为可退出队列和不可退出队列,activity中封装的那个的是可退出的)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值