1. 程式人生 > >使用WeakReference,解決 Handler class should be static or leaks might occur問題

使用WeakReference,解決 Handler class should be static or leaks might occur問題

首先定義一個Activity子類:

public class AutoActivity extends Activity {

Handler handler = new Handler(){
    public void handleMessage(android.os.Message msg) {

    };
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_auto);
}

}

報警告:This Handler class should be static or leaks might occur意思是:Handler 
類應該為static型別,否則可能會造成記憶體洩漏。

原因:當一個Android主執行緒被建立的時候,同時會有一個Looper物件被建立,而這個Looper物件會實現一個MessageQueue(訊息佇列),當我們建立一個handler物件時,而handler的作用就是放入和取出訊息從這個訊息佇列中,每當我們通過handler將一個msg放入訊息佇列時,這個msg就會持有一個handler物件的引用。因此當Activity被結束後,這個msg在被取出來之前,這msg會繼續存活,但是這個msg持有handler的引用,而handler在Activity中建立,會持有Activity的引用,因而當Activity結束後,Activity物件並不能夠被gc回收,因而出現記憶體洩漏。

解決: 
一:將hanlder物件宣告為靜態的物件。 
二:使用靜態內部類,通過WeakReference實現對Activity的弱引用。具體實現看以下程式碼:

public class AutoActivity extends Activity {

MyHandler handler = new MyHandler(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_auto);
}

static class MyHandler extends Handler{
    WeakReference<AutoActivity> mactivity;

    public MyHandler(AutoActivity activity){
        mactivity = new WeakReference<AutoActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);           
        switch (msg.what) {
        case 100:               
            //在這裡面處理msg
            //通過mactivity.get()獲取Activity的引用(即上下文context)
            break;              
        default:
            break;
        }
    }
}

}