Handler造成的內存泄漏

來看下面代碼,會引起內存泄漏

public class HandlerActivity extends Activity {
	//可能引起內存泄漏
	private final Handler mHandler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			//...
		}
	}
}

Handler 是和 Looper 以及 MessageQueue 一起工作的,在 Android 中,一個應用啓動後,系統默認會創建一個爲主線程

服務的Looper對象,該Looper 對象用於處理主線程的所有 Message 對象,它的生命週期貫穿於整個應用的生命週期。

主線程中使用的 Handler 都會默認綁定到這個 Looper 對象。在主線程中創建 Handler 對象時,它會立即關聯主線程Looper

對象的 MessageQueue,這時發送到 MessageQueue 中的 Message 對象都會持有這個 Handler 對象的引用,這樣在 

Looper 處理消息時才能回調到 Handler 的 handleMessage 方法。因此,如果 Message 還沒有被處理完成,那麼Handler

對象也就不會被垃圾回收。上面的代碼中,將 Handler 的實例聲明爲 HandlerActivity類的內部類。

而在 java 語言中,非靜態類內部匿名類持有外部類的一個隱式的引用,這樣就可能導致外部類無法被垃圾回收。

因此最終由於 MessageQueue 中的 Message 還沒有處理完成,就會持有Handler 對象的引用,而 非靜態的 Handler 

對象會持有外部類 HandlerActivity 的引用,這個 Activity 無法被垃圾回收,從而導致內存泄漏。

解決辦法:

1°  在子線程中使用 Handler,這時需要自己創建一個 Looper 對象,這個 Looper對象的生命週期同一般的java對象,因此

用這種用法沒問題。

2° 將Handler 聲明爲 靜態的內部類,前面說過,靜態內部類 不會持有外部類的引用,因此也不會引起內存泄漏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章