在Android開發(fā)中經(jīng)常會使用handler做定時任務(wù)或者更新UI等,但是handler在好用的同時也是非常容易導(dǎo)致內(nèi)存泄漏。因為handler在作為一個類的屬性時會持有該類(通常是activity或fragment)的引用,而handler在發(fā)送message時,該message的target通常就是handler本身,也就是通過handler發(fā)送的消息間接持有該類的引用。當該類應(yīng)當被回收,而消息隊列中還有沒處理的message時,該類也就無法被回收,從而導(dǎo)致了內(nèi)存泄漏。這個場景是及其常見的,因為handler經(jīng)常被用來發(fā)延時消息。
一個補救的辦法就是在該類需要回收的時候,手動地把消息隊列中的消息清空:
mHandler.removeCallbacksAndMessages(null);
這個方法用于有生命周期回調(diào)的組件中還好,稍微麻煩一點;若是在一個不知道該什么時候被回收的類里面,這個內(nèi)存泄漏也是不可預(yù)測的。故而有下面的解決方案:
/**
* 實現(xiàn)回調(diào)弱引用的Handler
* 防止由于內(nèi)部持有導(dǎo)致的內(nèi)存泄露
*
* PS:
* 1、傳入的Callback不能使用匿名實現(xiàn)的變量,必須與使用這個Handle的對象的生命周期一致,否則會被立即釋放掉了
*
* @author brian512
*/
public class WeakRefHandler extends Handler {
private WeakReference<Callback> mWeakReference;
public WeakRefHandler(Callback callback) {
mWeakReference = new WeakReference<Handler.Callback>(callback);
}
public WeakRefHandler(Callback callback, Looper looper) {
super(looper);
mWeakReference = new WeakReference<Handler.Callback>(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);
CodeBlog是我做的一個編程技術(shù)學習客戶端,集成了很多技術(shù)網(wǎng)站上的博客,應(yīng)用寶詳情頁