后臺(tái)線程任務(wù)處理完成后吱瘩,常用Handler來(lái)更新ui事件,常用代碼如下:
private Handler handler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
if (msg.what == 1) {
listAdapter.notifyDataSetChanged();
}
}
};
這段代碼可能造成內(nèi)存泄漏迹缀,原因是:Handler作為Activity的內(nèi)部類創(chuàng)建時(shí)使碾,隱式持有了外部類Activity的引用蜜徽。而Handler一般會(huì)伴隨一個(gè)耗時(shí)的后臺(tái)線程(如網(wǎng)絡(luò)下載圖片),當(dāng)后臺(tái)線程執(zhí)行完畢時(shí)票摇,通過handler來(lái)更新界面拘鞋。但如果在網(wǎng)絡(luò)請(qǐng)求的過程中關(guān)閉了Activity,此時(shí)線程尚未執(zhí)行完矢门,而該線程持有handler的引用盆色,handler又持有外部Activity的引用,導(dǎo)致該Activity無(wú)法被內(nèi)存回收祟剔,直到網(wǎng)絡(luò)請(qǐng)求結(jié)束隔躲。
類似的使用Hanlder.postDelayed方法,Message對(duì)象持有當(dāng)前handler的引用物延,而Message又存放在MessageQueue中宣旱,那么在dalay到達(dá)之前,一直會(huì)持有外部Activity的引用叛薯,導(dǎo)致內(nèi)存無(wú)法回收响鹃。
為了避免Handler引起的內(nèi)存泄漏,可以使用一下幾種方法
一案训、程序保護(hù)
1)在Activity關(guān)閉前,停止后臺(tái)線程粪糙;
2)在Activity關(guān)閉前强霎,刪除所有的待處理message。
// If null, all callbacks and messages will be removed.
mHandler.removeCallbacksAndMessages(null);
二蓉冈、靜態(tài)內(nèi)部類
在Java 中城舞,非靜態(tài)的內(nèi)部類和匿名內(nèi)部類都會(huì)隱式地持有其外部類的引用,靜態(tài)的內(nèi)部類不會(huì)持有外部類的引用寞酿。
可以使用弱引用來(lái)操作Activity中的對(duì)象家夺。
static class StaicHandler extends Handler {
WeakReference<Activity> mWeakReference;
public StaicHandler (Activity activity) {
mWeakReference = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
Activity activity = mWeakReference.get();
if(activity != null) {
if (msg.what == 1) {
activity.***
}
}
}
}