LeakCanary发现了Android WebView的内存泄漏问题。

7
我一直在使用一个工具leakcanary,用来检查应用程序中的内存泄漏问题。似乎我的WebViewActivity每次都会泄漏。
我创建了一个简单的应用程序来测试这些泄漏问题。我使用xml布局文件中的Activity上下文启动带有WebView的Activity。关闭Js,并且保持默认设置,除了一个简单的webViewClient,它将重定向限制在WebView内部。但是每次都会泄漏。
我已经进行了大量研究,唯一防止此类问题的方法是使用另一个进程启动WebViewActivity并在onDestroy()中销毁它。但是这种方法也存在自己的缺点。
泄漏问题每次在所有运行5.0+系统的设备上都会发生,在4.3及以下版本中还未检查。
泄漏信息如下:

In com.example.webviewmemoryleaktest:1.0:1. * com.example.webviewmemoryleaktest.WebViewActivity has leaked: * GC ROOT android.os.ResultReceiver$MyResultReceiver.this$0 * references org.chromium.content.browser.ContentViewCore$2$1.this$1 (anonymous class extends android.os.ResultReceiver) * references org.chromium.content.browser.ContentViewCore$2.this$0 * references org.chromium.content.browser.ContentViewCore.mContext * references com.android.webview.chromium.ResourcesContextWrapperFactory$WebViewContextWrapper.mBase * leaks com.example.webviewmemoryleaktest.WebViewActivity instance

  • Reference Key: 9a0346cf-6ad9-4b07-9329-a975d8fa3cbe
  • Device: LGE google Nexus 4 occam
  • Android Version: 5.1 API: 22
  • Durations: watch=5139ms, gc=188ms, heap dump=2822ms, analysis=30918ms
希望任何人都能提供帮助。谢谢!

他们有一个基于Android框架代码的泄漏处理记录程序。这也在LeakCanary文档中有所涵盖。https://github.com/square/leakcanary#my-leak-is-caused-by-the-android-sdk-implementation - CommonsWare
当您不再需要 WebView 并已将其从视图层次结构中删除时,是否调用 WebView.destroy() doc - Mikhail Naganov
是的,我已经尝试了mWebView.destroy()/mWebView = null/mWebView.load(about:blank),但都没有起作用。 - C.Allan
你有找到任何解决方法吗?并且你已经向谷歌报告了吗?我也遇到了同样的问题。 - Romain Piel
我也是。看起来这个问题应该在Chromium 42版本中得到修复(https://code.google.com/p/chromium/issues/detail?id=473146),但我的System WebView版本是44,而且仍然存在内存泄漏的问题。 - Allison
哦,我刚看到 @Allison ,你如何查找 Chromium 的版本?这也很有趣。 - Romain Piel
1个回答

0
private ResultReceiver mResultReceiver = new ResultReceiver(new Handler()) {
    @Override
    public void onReceiveResult(int resultCode, Bundle resultData) {
        getContentViewClient().onImeStateChangeRequested(
                resultCode == InputMethodManager.RESULT_SHOWN
                || resultCode == InputMethodManager.RESULT_UNCHANGED_SHOWN);
        if (resultCode == InputMethodManager.RESULT_SHOWN) {
            // If OSK is newly shown, delay the form focus until
            // the onSizeChanged (in order to adjust relative to the
            // new size).
            // TODO(jdduke): We should not assume that onSizeChanged will
            // always be called, crbug.com/294908.
            getContainerView().getWindowVisibleDisplayFrame(
                    mFocusPreOSKViewportRect);
        } else if (hasFocus() && resultCode
                == InputMethodManager.RESULT_UNCHANGED_SHOWN) {
            // If the OSK was already there, focus the form immediately.
            assert mWebContents != null;
            mWebContents.scrollFocusedEditableNodeIntoView();
        }
    }
};

@Override
public ResultReceiver getNewShowKeyboardReceiver() {
    return mResultReceiver;
}

将mResultReceiver设为私有。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接