談談handler的內存泄露問題
再來看看我們的新建Handler的代碼:
private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { ... } };
- 當使用內部類(包括匿名類)來創建Handler的時候,Handler對象會隱式地持有Activity的引用。
而Handler通常會伴隨着一個耗時的后台線程一起出現,這個后台線程在任務執行完畢后發送消息去更新UI。然而,如果用戶在網絡請求過程中關閉了Activity,正常情況下,Activity不再被使用,它就有可能在GC檢查時被回收掉,但由於這時線程尚未執行完,而該線程持有Handler的引用(不然它怎么發消息給Handler?),這個Handler又持有Activity的引用,就導致該Activity無法被回收(即內存泄露),直到網絡請求結束。
另外,如果執行了Handler的postDelayed()方法,那么在設定的delay到達之前,會有一條MessageQueue -> Message -> Handler -> Activity的鏈,導致你的Activity被持有引用而無法被回收。
解決方法之一,使用弱引用:
static class MyHandler extends Handler { WeakReference<Activity > mActivityReference; MyHandler(Activity activity) { mActivityReference= new WeakReference<Activity>(activity); } @Override public void handleMessage(Message msg) { final Activity activity = mActivityReference.get(); if (activity != null) { mImageView.setImageBitmap(mBitmap); } } }
https://blog.csdn.net/ly502541243/article/details/52062179
其他handler的替代方案:
EventBus事件總線——優雅地替換Handler
https://blog.csdn.net/stimgo/article/details/52684390
RxJava線程切換代替Thread和Handler
https://www.jianshu.com/p/9d4e39a83a74
RxAndroid 進行封裝實現替代Handler的方案
https://blog.csdn.net/z2wenfa/article/details/51276626
使用RxJava和RxAndroid封裝RxBus,實現EventBus功能
https://blog.csdn.net/qq_33689414/article/details/51586250
給 Android 開發者的 RxJava 詳解
http://gank.io/post/560e15be2dca930e00da1083