來看下面代碼,會引起內存泄漏
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 聲明爲 靜態的內部類,前面說過,靜態內部類 不會持有外部類的引用,因此也不會引起內存泄漏。