內(nèi)存泄漏:沒有用的對象间聊,無法被GC垃圾回收笆焰,就會造成內(nèi)存泄漏(OOM)
Handler如果使用不當(dāng)蓬豁,極大可能造成內(nèi)存泄漏谆奥。比如:我們一般使用handler的方式眼坏,會在主線程中使用匿名類來創(chuàng)建handler:
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
內(nèi)存泄漏的原因:
在Java 中,非靜態(tài)的內(nèi)部類和匿名內(nèi)部類都會隱式地持有其外部類的引用酸些,靜態(tài)的內(nèi)部類不會持有外部類的引用宰译。
而由于Handler原來,MessageQueue中的Message會對Handler持有引用魄懂,而handler會對Activity持有引用沿侈,即:
message -----> handler ----->activity所以,當(dāng)Activity被銷毀時市栗,如果MessageQueue中仍然有message沒有處理完缀拭,就會一直持有對Activity的引用,導(dǎo)致GC無法回收Activity填帽,由此造成內(nèi)存泄漏蛛淋。
兩種解決方法:
- 將Handler定義為靜態(tài)內(nèi)部類,提高調(diào)用WeakReference來完成handler對Activity的弱引用篡腌。GC回收機制規(guī)定褐荷,當(dāng)對象被其他對象弱引用時,允許GC對其回收嘹悼。具體的代碼實現(xiàn):
private static class MyHandler extends Handler{
private WeakReference<MainActivity> weakReference;
public MyHandler(MainActivity activity){
weakReference = new WeakReference<>(activity);
}
Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
final Activity activity = weakReference.get();
if (activity != null) {
//實現(xiàn)相應(yīng)邏輯
}
}
}
- 在Activity被銷毀時叛甫,將未處理的message全部remove层宫。代碼實現(xiàn):
@Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacksAndMessages(null);
}
這樣使用Handler,就不會造成內(nèi)存泄漏了其监。