先来看一段代码:
1. private Handler mHandler = new Handler() {
2. @Override
3. public void handleMessage(Message msg) {
4. // ...
5. }
6. };
这样的写法eclipse会给出一个leak的提示This Handler class should be static or leaks might occur...,表示有可能出现内存泄漏,分析如下:
1) 当一个Handler对象在主线程中创建的时候,它会关联到Looper的message queue。Message添加到消息队列中的时候Message会持有当前Handler引用,当Looper处理到当前消息的时候,会调用Handler#handleMessage(Message).
2) 在java中,no-static的内部类会 隐式的 持有当前类的一个引用。static的类则没有。
3) 总结:由于非静态内部类Handler会持有外部类对象的引用,而Handler又由于Message处理的方式有可能常驻内存当中。这样就会导致外部的Activity或者Service在销毁之后无法及时被GC回收,甚至内存泄漏。
为此,为了避免泄露这个外部类,应该将Handler声明为static嵌套类,并且使用对外部类的弱应用。
1. static class MsgHandler extends Handler {
2. private WeakReference<Activity> mActivity;
3.
4. MsgHandler(Activity activity) {
5. mActivity = new WeakReference<Activity>(activity);
6. }
7.
8. @Override
9. public void handleMessage(Message msg) {
10. Activity activity = mActivity.get();
11. if (activity != null) {
12. activity.handleMessage(msg);
13. }
14. }
15. }
16.
17. private Handler mHandler = new MsgHandler(this);