如何避免使用Handler造成的内存泄漏

一、什么是内存泄漏?

对象已经没有被应用程序使用,由于引用或者其它垃圾回收器不能或者无法回收它们。

二、Activity中使用Handler为什么会造成泄漏

1.非静态的内部类和匿名内部类都会隐式地持有其外部类的引用

2.new Handler(){}是匿名内部内构造对象的格式

1
2
3
4
new 父类构造器(参数列表)|实现接口()  
{
//匿名内部类的类体部分
}

匿部类的形式构造Handler

1
2
3
4
5
6
7
8
9
10
/**
* 匿名内部类构造Handeler对象,默认持有外部类引用
*/
private Handler mHandler=new Handler()
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};

三、如何避免使用Handler造成内存泄漏

1.声明静态内部内和弱引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private MyHandler myHandler=new MyHandler(this);
/**
*1. 声明静态内部类(静态的内部类不会持有外部类的引用)
* 2.声明弱引用(GC在回收时会忽略掉弱引用,直接回收)
*/
static class MyHandler extends Handler {
WeakReference<Activity> mActivityReference;
MyHandler(Activity activity) {
//弱引用
mActivityReference= new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what)
{
case 1:
final Activity activity = mActivityReference.get();
/**
* 执行些界面操作,更新等
*
*/
Log.w("leakHandler","MyHandler没有释放,还在执行任务哦~o~:");
break;
}

}
}

2.onDestroy()的时候调用Handler的removeCallbacksAndMessages(null),清除所有回调和消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
protected void onDestroy() {
super.onDestroy();
/**
* 移除回调和消息
*/
if (myHandler != null)
myHandler.removeCallbacksAndMessages(null);
/**
* leakCanary去观察myHandler是否泄露了
*/
//MyApp.getRefWatcher(this).watch(myHandler);

}