在Android開發(fā)中經(jīng)常會(huì)使用handler做定時(shí)任務(wù)或者更新UI等绑榴,但是handler在好用的同時(shí)也是非常容易導(dǎo)致內(nèi)存泄漏哪轿。因?yàn)閔andler在作為一個(gè)類的屬性時(shí)會(huì)持有該類(通常是activity或fragment)的引用,而handler在發(fā)送message時(shí)翔怎,該message的target通常就是handler本身窃诉,也就是通過handler發(fā)送的消息間接持有該類的引用驮肉。當(dāng)該類應(yīng)當(dāng)被回收劈榨,而消息隊(duì)列中還有沒處理的message時(shí)入录,該類也就無法被回收醋虏,從而導(dǎo)致了內(nèi)存泄漏软族。這個(gè)場景是及其常見的连舍,因?yàn)閔andler經(jīng)常被用來發(fā)延時(shí)消息庶喜。
一個(gè)補(bǔ)救的辦法就是在該類需要回收的時(shí)候桑寨,手動(dòng)地把消息隊(duì)列中的消息清空:
mHandler.removeCallbacksAndMessages(null);
這個(gè)方法用于有生命周期回調(diào)的組件中還好唯沮,稍微麻煩一點(diǎn)脖旱;若是在一個(gè)不知道該什么時(shí)候被回收的類里面,這個(gè)內(nèi)存泄漏也是不可預(yù)測的介蛉。故而有下面的解決方案:
/**
* 實(shí)現(xiàn)回調(diào)弱引用的Handler
* 防止由于內(nèi)部持有導(dǎo)致的內(nèi)存泄露
*
* PS:
* 1萌庆、傳入的Callback不能使用匿名實(shí)現(xiàn)的變量,必須與使用這個(gè)Handle的對象的生命周期一致币旧,否則會(huì)被立即釋放掉了
*
* @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);
}
}
}
由于是弱引用践险,當(dāng)該類需要被回收時(shí),就可以直接被回收掉吹菱。
WeakRefHandler的使用時(shí)如下:
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是我做的一個(gè)編程技術(shù)學(xué)習(xí)客戶端巍虫,集成了很多技術(shù)網(wǎng)站上的博客,應(yīng)用寶詳情頁