內存泄漏:沒有用的對象,無法被GC垃圾回收,就會造成內存泄漏(OOM)
Handler如果使用不當,極大可能造成內存泄漏。比如:我們一般使用handler的方式,會在主線程中使用匿名類來創建handler:
Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); } };
內存泄漏的原因:
-
在Java 中,非靜態的內部類和匿名內部類都會隱式地持有其外部類的引用,靜態的內部類不會持有外部類的引用。
-
而由於Handler原來,MessageQueue中的Message會對Handler持有引用,而handler會對Activity持有引用,即:
message -----> handler ----->activity -
所以,當Activity被銷毀時,如果MessageQueue中仍然有message沒有處理完,就會一直持有對Activity的引用,導致GC無法回收Activity,由此造成內存泄漏。
兩種解決方法:
- 將Handler定義為靜態內部類,提高調用WeakReference來完成handler對Activity的弱引用。GC回收機制規定,當對象被其他對象弱引用時,允許GC對其回收。具體的代碼實現:
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) { //實現相應邏輯 } } }
2 在Activity被銷毀時,將未處理的message全部remove。代碼實現:
@Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); }
這樣使用Handler,就不會造成內存泄漏了。