在Android開發中經常會使用handler做定時任務或者更新UI等,但是handler在好用的同時也是非常容易導致內存泄漏。因為handler在作為一個類的屬性時會持有該類(通常是activity或fragment)的引用,而handler在發送message時,該message的target通常就是handler本身,也就是通過handler發送的消息間接持有該類的引用。當該類應當被回收,而消息隊列中還有沒處理的message時,該類也就無法被回收,從而導致了內存泄漏。這個場景是及其常見的,因為handler經常被用來發延時消息。
一個補救的辦法就是在該類需要回收的時候,手動地把消息隊列中的消息清空:
mHandler.removeCallbacksAndMessages(null);
這個方法用于有生命周期回調的組件中還好,稍微麻煩一點;若是在一個不知道該什么時候被回收的類里面,這個內存泄漏也是不可預測的。故而有下面的解決方案:
/** * 實現回調弱引用的Handler * 防止由于內部持有導致的內存泄露 * * PS: * 1、傳入的Callback不能使用匿名實現的變量,必須與使用這個Handle的對象的生命周期一致,否則會被立即釋放掉了 * * @author brian512 */ public class WeakRefHandler extends Handler { private WeakReferencelt;Callbackgt; mWeakReference; public WeakRefHandler(Callback callback) { mWeakReference = new WeakReferencelt;Handler.Callbackgt;(callback); } public WeakRefHandler(Callback callback, Looper looper) { super(looper); mWeakReference = new WeakReferencelt;Handler.Callbackgt;(callback); } @Override public void handleMessage(Message msg) { if (mWeakReference != null mWeakReference.get() != null) { Callback callback = mWeakReference.get(); callback.handleMessage(msg); } } }
由于是弱引用,當該類需要被回收時,就可以直接被回收掉。
WeakRefHandler的使用時如下:
private Handler.Callback mCallback = new Handler.Callback() { @Override public boolean handleMessage(Message msg) { switch(msg.what){ } return true; } }; private Handler mHandler = new WeakRefHandler(mCallback);
Tags: 安卓開發
文章來源:http://www.jianshu.com/p/88cf7a923b56