1. 说Handler内存泄露这种文章挺多的,基本就是handler 使用不当 持有外部引用导致的内存泄露完毕.
泄露的两种情况 1.静态handler变量 引用外部变量; 2.非静态Handler 对象引用外部变量
第一种
private static Handler mHandler=new Handler(){
...
};
第二种
private Handler mHandler=new Handler(){
...
};
第一种没啥好说的,只讨论第二种。
2.根据可达性gc 算法,当一个引用没有被root 对象引用时,该对象内存随时被系统回收,那么handler 的引用链又是什么呢?
未指定Looper 默认就使用主Looper ,那么主Looper 在哪里创建呢?在ActivityThread类中 :
public static void main(String[] args) {
...
//主looper 比Application 创建的还要早
Looper.prepareMainLooper();
// Service端 调用bindApplication,收到ActivityThread 收到binder消息后, 使用handler 发送消息创建Application
ActivityThread thread = new ActivityThread();
thread.attach(false);
....
//死循环
Looper.loop();
...
throw new RuntimeException("Main thread loop unexpectedly exited");
}
意不意外惊不惊喜,比Applicaion 创建还要早,从原理上来说调用 removeCallbacksAndMessages 方法一样可以解决泄露,当然也可以从Handler 去掉外部引用.
ps:记得有一次面试问Handler 内存泄露问题,本人阐述跟上面差不多意思,最后反问我Handler内存泄露不是 Handler引用外部对象导致的吗,...。我觉得这句话半对半错,因为外部对象跟handler 对象生命周期一样,垃圾算法不是引用计数法,当然你说第一种情况你也站的住。