目录
前言
Android代码中涉及进程间通信的地方经常会使用Handler。1
2
3
4
5
6
7
8
9
10
11
12
13
14public class MainActivity extends AppCompatActivity {
//可能引入内存泄漏的方法
private Handler handler=new Handler(){
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
而上面这种用法可能会导致内存泄漏,比如使用如下代码,由于消息会在5分钟后发送,所以当用户进入并退出Activity后,在消息发送并处理完成之前,这个Activity是不会被回收的,这样就会导致内存泄漏。
1 | public class MainActivity extends AppCompatActivity { |
内存泄漏的原因
由于Handler、Looper和MessageQueue是一起工作的,在Android中一个应用启动后系统会默认创建一个用于处理主线程所有Message对象的Looper对象,它的生命周期贯穿于整个应用的生命周期,所以在主线程使用Handler的时候都会默认绑定这个Looper对象并关联MessageQueue,这时发送到MessageQueue的Message对象都会持有这个Handler对象的引用,这样Looper在处理消息的时候才能回调到Handler中年的handleMessage方法。因此如果Message对象还没有处理完成,那么Handler对象也就不会被垃圾回收。而在Java中非静态内部类会持有外部类的一个隐式引用,所以当Handler无法回收时由于Handler持有MainActivity的引用导致MainActivity也无法被回收,从而导致内存泄漏。
解决方法:将Handler改为静态内部类并使用弱引用
1 | public class MainActivity extends AppCompatActivity { |