WebView内存泄露解决方案

849 阅读1分钟

泄漏原因

5.1系统以上,存在未回收的对象,AwContents中注册了mComponentCallbacks没有反注册

AwContents.java

@Override
        public void onAttachedToWindow() {
            if (isDestroyed()) return;
            if (mIsAttachedToWindow) {
                Log.w(TAG, "onAttachedToWindow called when already attached. Ignoring");
                return;
            }
            mIsAttachedToWindow = true;
            mContentViewCore.onAttachedToWindow();
            nativeOnAttachedToWindow(mNativeAwContents, mContainerView.getWidth(),
                    mContainerView.getHeight());
            updateHardwareAcceleratedFeaturesToggle();
            if (mComponentCallbacks != null) return;
            mComponentCallbacks = new AwComponentCallbacks();
            mContext.registerComponentCallbacks(mComponentCallbacks);
        }
        @Override
        public void onDetachedFromWindow() {
            // 如果已经destroy了,直接返回,就跳过了反注册
            if (isDestroyed()) return;
            if (!mIsAttachedToWindow) {
                Log.w(TAG, "onDetachedFromWindow called when already detached. Ignoring");
                return;
            }
            mIsAttachedToWindow = false;
            hideAutofillPopup();
            nativeOnDetachedFromWindow(mNativeAwContents);
            mContentViewCore.onDetachedFromWindow();
            updateHardwareAcceleratedFeaturesToggle();
            if (mComponentCallbacks != null) {
                mContext.unregisterComponentCallbacks(mComponentCallbacks);
                mComponentCallbacks = null;
            }
            mScrollAccessibilityHelper.removePostedCallbacks();
            mNativeGLDelegate.detachGLFunctor();
        }

WebView destroy

public void destroy() { 
    mIsDestroyed = true;
    destroyNatives(); 
}

执行了webView的destroy后就无法反注册

解决方案

在代码里创建WebView,手动添加到界面中,onDestroy中手动移除WebView,切断引用链,之后再执行webView的destroy方法。