天天看點

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 聲明為 靜态的内部類,前面說過,靜态内部類 不會持有外部類的引用,是以也不會引起記憶體洩漏。

繼續閱讀