Android Handler的内存泄露问题+解决方案

谈谈handler的内存泄露问题

再来看看我们的新建Handler的代码:

private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            ...
        }
    };
  • 当使用内部类(包括匿名类)来创建Handler的时候,Handler对象会隐式地持有Activity的引用。

而Handler通常会伴随着一个耗时的后台线程一起出现,这个后台线程在任务执行完毕后发送消息去更新UI。然而,如果用户在网络请求过程中关闭了Activity,正常情况下,Activity不再被使用,它就有可能在GC检查时被回收掉,但由于这时线程尚未执行完,而该线程持有Handler的引用(不然它怎么发消息给Handler?),这个Handler又持有Activity的引用,就导致该Activity无法被回收(即内存泄露),直到网络请求结束。

另外,如果执行了Handler的postDelayed()方法,那么在设定的delay到达之前,会有一条MessageQueue -> Message -> Handler -> Activity的链,导致你的Activity被持有引用而无法被回收。

解决方法之一,使用弱引用:

static class MyHandler extends Handler {
    WeakReference<Activity > mActivityReference;
    MyHandler(Activity activity) {
        mActivityReference= new WeakReference<Activity>(activity);
    }
    @Override
    public void handleMessage(Message msg) {
        final Activity activity = mActivityReference.get();
        if (activity != null) {
            mImageView.setImageBitmap(mBitmap);
        }
    }
}

https://blog.csdn.net/ly502541243/article/details/52062179


其他handler的替代方案:

EventBus事件总线——优雅地替换Handler
https://blog.csdn.net/stimgo/article/details/52684390

RxJava线程切换代替Thread和Handler
https://www.jianshu.com/p/9d4e39a83a74

RxAndroid 进行封装实现替代Handler的方案
https://blog.csdn.net/z2wenfa/article/details/51276626

使用RxJava和RxAndroid封装RxBus,实现EventBus功能
https://blog.csdn.net/qq_33689414/article/details/51586250

 

给 Android 开发者的 RxJava 详解
http://gank.io/post/560e15be2dca930e00da1083

 

posted @ 2018-06-27 10:11  petercao  阅读(3391)  评论(0编辑  收藏  举报