阅读628 返回首页    go 阿里云 go 技术社区[云栖]


Android中Handler可能引起内存泄露

先来看一段代码:

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);

最后更新:2017-04-03 06:03:10

  上一篇:go 移动App该如何保存用户密码
  下一篇:go 结构体、枚举