Android WebView窗口泄露

时间:2016-12-22 09:02:33

标签: android webview

我在使用WebView的大项目中遇到过这个问题,但是当我发现代码没有任何问题时,我做了一个只包含两件事的简单项目:

使用此特定代码的MainActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    WebView webView = (WebView) findViewById(R.id.webView);
    Uri uri = Uri.parse("android.resource://whatever");
    webView.loadUrl(uri.toString());
}

activity_main.xml 仅包含布局和Webview。没别了。

现在,webview显示一条消息,表明它无法显示网站,这没关系。它是否显示无关紧要。这是交易:当我选择一个文本并弹出显示(带有复制|粘贴),然后我返回单击后退按钮(导致关闭活动),我得到以下异常(没有崩溃):

E/Surface: getSlotFromBufferLocked: unknown buffer: 0x7fb64bfadb20
E/WindowManager: android.view.WindowLeaked: Activity com.example.***.richwebeditor.MainActivity has leaked window android.widget.PopupWindow$PopupDecorView{ffd5bff V.E...... ........ 0,0-116,58} that was originally added here
      at android.view.ViewRootImpl.<init>(ViewRootImpl.java:368)
      at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299)
      at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
      at android.widget.PopupWindow.invokePopup(PopupWindow.java:1258)
      at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1032)
      at android.widget.PopupWindow.showAtLocation(PopupWindow.java:995)
      at org.chromium.content.browser.input.PopupTouchHandleDrawable.show(PopupTouchHandleDrawable.java:354)
      at org.chromium.android_webview.AwContents.nativeOnDraw(Native Method)
      at org.chromium.android_webview.AwContents.access$4500(AwContents.java:92)
      at org.chromium.android_webview.AwContents$AwViewMethodsImpl.onDraw(AwContents.java:2731)
      at org.chromium.android_webview.AwContents.onDraw(AwContents.java:1191)
      at com.android.webview.chromium.WebViewChromium.onDraw(WebViewChromium.java:1713)
      at android.webkit.WebView.onDraw(WebView.java:2486)
      at android.view.View.draw(View.java:16178)
      at android.view.View.updateDisplayListIfDirty(View.java:15174)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
      at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
      at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
      at android.view.ViewRootImpl.draw(ViewRootImpl.java:2615)
      at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2434)
      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2067)
      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
      at android.view.Choreographer.doCallbacks(Choreographer.java:670)
      at android.view.Choreographer.doFrame(Choreographer.java:606)
      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
      at android.os.Handler.handleCallback(Handler.java:739)
      at android.os.Handler.dispatchMessage(Handler.java:95)
      at android.os.Looper.loop(Looper.java:148)
      at android.app.ActivityThread.main(ActivityThread.java:5417)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

E/Surface: getSlotFromBufferLocked: unknown buffer: 0x7fb63de30880
E/WindowManager: android.view.WindowLeaked: Activity com.example.***.richwebeditor.MainActivity has leaked window android.widget.PopupWindow$PopupDecorView{7220dcc V.E...... ........ 0,0-116,58} that was originally added here
      at android.view.ViewRootImpl.<init>(ViewRootImpl.java:368)
      at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299)
      at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
      at android.widget.PopupWindow.invokePopup(PopupWindow.java:1258)
      at android.widget.PopupWindow.showAtLocation(PopupWindow.java:1032)
      at android.widget.PopupWindow.showAtLocation(PopupWindow.java:995)
      at org.chromium.content.browser.input.PopupTouchHandleDrawable.show(PopupTouchHandleDrawable.java:354)
      at org.chromium.android_webview.AwContents.nativeOnDraw(Native Method)
      at org.chromium.android_webview.AwContents.access$4500(AwContents.java:92)
      at org.chromium.android_webview.AwContents$AwViewMethodsImpl.onDraw(AwContents.java:2731)
      at org.chromium.android_webview.AwContents.onDraw(AwContents.java:1191)
      at com.android.webview.chromium.WebViewChromium.onDraw(WebViewChromium.java:1713)
      at android.webkit.WebView.onDraw(WebView.java:2486)
      at android.view.View.draw(View.java:16178)
      at android.view.View.updateDisplayListIfDirty(View.java:15174)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3593)
      at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3573)
      at android.view.View.updateDisplayListIfDirty(View.java:15134)
      at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:281)
      at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:287)
      at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:322)
      at android.view.ViewRootImpl.draw(ViewRootImpl.java:2615)
      at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2434)
      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2067)
      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
      at android.view.Choreographer.doCallbacks(Choreographer.java:670)
      at android.view.Choreographer.doFrame(Choreographer.java:606)
      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
      at android.os.Handler.handleCallback(Handler.java:739)
      at android.os.Handler.dispatchMessage(Handler.java:95)
      at android.os.Looper.loop(Looper.java:148)
      at android.app.ActivityThread.main(ActivityThread.java:5417)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
E/Surface: getSlotFromBufferLocked: unknown buffer: 0x7fb63de30340

我在三个不同的三星Galaxy设备(Android 6.1),一个模拟器(7.0)和一个旧的HTC手机(5.0)上进行了测试。我在每种情况下都有例外。

有没有人遇到过这个问题?这是Android webview的错误吗?有解决方案吗?

编辑: 关于我正在谈论的弹出窗口的参考屏幕:

Imgur1

Imgur2

3 个答案:

答案 0 :(得分:1)

看起来这个问题的一个好方法是调用

webView.destroy()

完成活动时。我相信这个问题有一个更好的解决方案,并且会让这个问题暂时解决,所以也许经验丰富的人会分享处理它的正确方法。

答案 1 :(得分:0)

如果您想从网络视图中返回,请在该活动中使用此功能

@Override
public void onBackPressed() {
    if (webView.canGoBack()) {
        webView.goBack();
    } else {
        super.onBackPressed(); // maybe you can even change this as needed
    }
}

- 您创建了一项活动。

-Spawn一个工作线程,它引用了该活动。   - 活动以某种方式关闭/完成()(最有可能是用户交互的结果),系统尝试收集其资源。

- 工作线程仍在运行并且其持有对活动的引用......因此活动已经泄露了#39;并且系统无法在不以潜在危险的方式改变/破坏您的应用程序状态的情况下自由回收它。

-Activities是Android中的重量级对象,(激进的)系统资源管理器需要能够回收它们以确保为用户提供流畅和高效的体验。所以这个&#39;泄漏&#39;被认为是错误。

- 在这些情况下,检查参考仍然存在于您的行动之前

答案 2 :(得分:0)

也许您应该在完成活动之前释放text.split(/(?m)^\/$/) ^^^^ 使用的资源,尝试在WebView中添加 webView.loadUrl("about:blank");