谈谈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

04-20 23:30