1. 程式人生 > >從根源解決WebView記憶體洩漏

從根源解決WebView記憶體洩漏

本人CSDN和github部落格連結地址和各專案下載連結地址

CSDN部落格連結地址:點選開啟連結

github部落格連結地址:點選開啟連結

webview引起的記憶體洩漏主要是因為

org.chromium.android_webview.AwContents 類中註冊了component callbacks,但是未正常反註冊而導致的。
org.chromium.android_webview.AwContents 類中有這兩個方法 onAttachedToWindow 和 onDetachedFromWindow;
系統會在attach和detach處進行註冊和反註冊component callback;

在onDetachedFromWindow() 方法的第一行中:

if (isDestroyed()) 
	return;

如果 isDestroyed() 返回 true 的話,那麼後續的邏輯就不能正常走到,所以就不會執行unregister的操作;
我們的activity退出的時候,都會主動呼叫 WebView.destroy() 方法,這會導致 isDestroyed() 返回 true;
destroy()的執行時間又在onDetachedFromWindow之前,所以就會導致不能正常進行unregister()。
然後解決方法就是:讓onDetachedFromWindow先走,在主動呼叫destroy()之前,把webview從它的parent上面移除掉。
ViewParent parent = mWebView.getParent();
if (parent != null) {
    ((ViewGroup) parent).removeView(mWebView);
}

mWebView.destroy();
完整的activity的onDestroy()方法:
@Override
protected void onDestroy() {
    if( mWebView!=null) {

        // 如果先呼叫destroy()方法,則會命中if (isDestroyed()) return;這一行程式碼,需要先onDetachedFromWindow(),再
        // destory()
        ViewParent parent = mWebView.getParent();
        if (parent != null) {
            ((ViewGroup) parent).removeView(mWebView);
        }

        mWebView.stopLoading();
        // 退出時呼叫此方法,移除繫結的服務,否則某些特定系統會報錯
        mWebView.getSettings().setJavaScriptEnabled(false);
        mWebView.clearHistory();
        mWebView.clearView();
        mWebView.removeAllViews();
        mWebView.destroy();

    }
    super.on Destroy();
}
作者:wencymu
連結:https://www.jianshu.com/p/3e8f7dbb0dc7
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。