1. Reasons for memory leaks caused by Handler
In the Activity, declare the Handler as a non-static inner class or an anonymous inner class, so that the Handle holds a reference to the outer class Activity by default. If the Activity is being destroyed, the Handler still has unfinished or executing Messages, and the Handler holds a reference to the Activity, causing the GC to fail to recycle the Activity, resulting in a memory leak. The following two situations may lead to memory leaks
1. Declare Handler as an anonymous inner class in Activity
//匿名内部类
private Handler mHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
};
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//大量的操作,activity要销毁时还没结束
}
},1000);
2. Declare Handler as a non-static inner class in Activity:
//非静态内部类
private class MyHandler extends Handler{
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
}
private MyHandler mHandler = new MyHandler();
Two, the solution
1. Static inner class + weak reference
private static class MyHandler extends Handler {
//弱引用,在垃圾回收时,activity可被回收
private WeakReference<MainActivity> mWeakReference;
public MyHandler(MainActivity activity) {
mWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
}
2. When the Activity is destroyed, clear the unexecuted or executing Callback and Message in the Handler:
@Override
protected void onDestroy() {
super.onDestroy();
//清空handler管道和队列
mHandler.removeCallbacksAndMessages(null);
}
3: Non-static inner class + weak reference, clear the reference when the activity is about to be recycled (troublesome, not recommended)
private class MyHandler extends Handler {
//弱引用,在垃圾回收时,activity可被回收
private WeakReference<MainActivity> mWeakReference;
public MyHandler() {
this.mWeakReference = new WeakReference<>(MainActivity.this);
}
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
}
private MyHandler mHandler = new MyHandler();
@Override
protected void onDestroy() {
super.onDestroy();
//手动清除应用
mHandler.mWeakReference.clear();
}