本文分兩部分
- Handler內(nèi)存泄漏例子及原理闡明
- Handler內(nèi)存泄露解決方案及說明
1. Handler內(nèi)存泄漏例子及原理闡明
private Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
};
private void anotherFun() {
handler.postDelayed(overlayRuuable, 500);
}
如上碌更,這是一個典型的Handler內(nèi)存泄露寫法迫筑,IDE會通過黃色警告塊提示我們:
This Handler class should be static or leak might occur (anonymous android.os.Handler)
那為什么會這樣呢十减?
- 在JAVA的非靜態(tài)內(nèi)部類和匿名內(nèi)部類都會隱式持有當(dāng)前類的外部引用,由于Handler屬于非靜態(tài)內(nèi)部類撰茎,所以其持有當(dāng)前Activity的隱式引用嵌牺,如果Handler沒有被釋放,其持有的Activity的引用也無法被釋放乾吻,進(jìn)而導(dǎo)致Activity持有的很多對象資源無法回收髓梅,這就產(chǎn)生了內(nèi)存泄漏問題拟蜻。
2. Handler內(nèi)存泄露解決方案及說明
解決Handler內(nèi)存泄露問題的方式就是 定義一個靜態(tài)內(nèi)部類繼承Handler绎签。因為靜態(tài)內(nèi)部類不會持有對外部類實例的引用,所以不會導(dǎo)致外部類實例的內(nèi)存泄露酝锅。
如果需要調(diào)用外部類的對象實例诡必,可以使用弱引用方法處理。
另外同樣需要將Runnable也設(shè)置為靜態(tài)的成員屬性
private static class LocalCounterDownHandler extends Handler {
private final WeakReference<CounterDownTextView> weakcountDownView;
public LocalCounterDownHandler(CounterDownTextView countDownView) {
weakcountDownView = new WeakReference<>(countDownView);
}
@Override
public void handleMessage(@NonNull Message msg) {
CounterDownTextView countDownView = weakcountDownView.get();
super.handleMessage(msg);
if (countDownView != null) {
countDownView.finish();
countDownView.setEnabled(true);
countDownView.setText("獲取驗證碼");
}
}
}
private void callFunction() {
LocalCounterDownHandler localCounterDownHandler = new LocalCounterDownHandler(countDownView);
localCounterDownHandler.sendEmptyMessage(0);
}