閱讀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 結構體、枚舉