Android Handler使用的安全问题

本文深入探讨了Android中使用Handler进行线程间通讯时可能引起的内存泄漏问题,详细解释了匿名内部类导致的问题根源,并提供了两种避免内存泄漏的有效解决方案:通过静态内部类实现弱引用,以及使用Handler.Callback接口结合弱引用。

android中使用Handler进行线程间通讯和消息的异步处理,在定义Handler时,有多种不同方式,常用的如

Handler handler = new Handler(){...}

这种写法存在内存泄漏风险,因为handler会持有匿名对象的引用,匿名对象会持有外部类对象的引用,且handler的生命周期较为特殊,并不会随activity(或fragment)结束而结束,所以,如果activity结束了,但是你的handler还存在未处理完的消息,其生命还在,这时候handler会阻止activity的回收,则会引起内存泄漏等不可控风险。

正确做法有两种:

1.静态内部类实现,这是最标准的写法。

 

private MyHandler handler = new MyHandler(this);
static class MyHandler extends Handler {
        WeakReference weakReference;
        public MyHandler(SecondActivity activity) {
            weakReference = new WeakReference(activity);
        }
 
        @Override
        public void handleMessage(Message msg) {
            
        }
    }

对外部类进行弱引用,GC时此引用可被自动回收。

2.使用Handler.Callback接口

private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            return false;
        }
    });

此方法需要在onDestroy方法中调用handler.removeCallbacksAndMessages(null); 来清空消息。或者加入用弱引用

Handler handler = new Handler(new WeakReference<Handler.Callbacks>(new Handler.Callback(
    @overridepublic 
    boolean handleMessage(Message msg) {
    })).get());

这样在堆中匿名对象只有指向它的弱引用,gc回收可以回收它。

参考:https://blog.youkuaiyun.com/try_zp_catch/article/details/78900031

           https://www.jianshu.com/p/41abcdd72bda

           https://blog.youkuaiyun.com/androidsj/article/details/79865091

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值