大家都知道,在很久之前,谷歌就發出警告This Handler class should be static or leaks might occur,不要在Activity中直接 new 一個Handler使用,因爲這樣創建Handler是一個內部類,會默認持有外部類的引用,就是Activity的引用,可能造成內存泄漏,類似於這樣:
什麼情況下會造成內存泄漏呢?比如你在Activity中使用了postDelay方法,延遲的操作還沒有執行,但是用戶點擊返回鍵退出了這個Activity,按照正常的程序這個Activity應該被銷燬,但是由於Handler持有Activity引用,導致Activity無法被回收,就會導致內存泄漏。所以在新版本的Android Studio上,只要是直接創建內部類Handler的,都會有一片黃色警告,谷歌的建議是把Handler做成靜態內部類,因爲靜態內部類不持有外部類的引用,就不會造成內存泄漏。
但是Handler做成靜態內部類不能直接訪問外部類的資源,所以要怎麼辦呢?這時候就需要用到弱引用了。
我們可以寫一個通用的父類Handler,然後在具體的Handler創建的時候繼承它,就可以避免內存泄漏,省時省力:
這個父類Handler代碼如下:
public class StaticHandler<T> extends Handler {
private static final String TAG = "StaticHandler";
protected WeakReference<T> ref;
public StaticHandler(T t) {
super();
ref = new WeakReference<T>(t);
}
@Override
public void handleMessage(Message msg) {
final T t = ref.get();
if (t == null) {
Log.w(TAG, "ref.get is null");
return;
}
handleMessage(msg, t);
}
protected void handleMessage(Message msg, T t) {
}
}
在Activity中是這樣使用的:
這樣可以消除黃色警告,又可以避免內存泄漏。
記住,創建Handler繼承於StaticHandler別忘了static關鍵字,這個很重要,必須是靜態內部類才能避免內存泄漏