使用 WebView 容器时出现 Android BadTokenException 错误

7
我遵循了一个关于避免WebView内存泄漏的帖子,建议使用WebView容器,然后在活动代码中以编程方式添加/删除WebView到容器中:Memory leak in WebView 然而,当单击提示选择选项列表的HTML元素时(例如日期/月份下拉菜单),我遇到了以下崩溃。
W/dalvikvm(17767): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)
W/WindowManager(129): Attempted to add window with non-application token WindowToken{4094b730 token=null}.  Aborting.
FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
 android.view.ViewRoot.setView(ViewRoot.java:561)
 android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
 android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
 android.app.Dialog.show(Dialog.java:265)
 android.webkit.WebView$InvokeListBox.run(WebView.java:9170)
 android.os.Handler.handleCallback(Handler.java:587)
 android.os.Handler.dispatchMessage(Handler.java:92)
 android.os.Looper.loop(Looper.java:150)
 android.app.ActivityThread.main(ActivityThread.java:4263)
 java.lang.reflect.Method.invokeNative(Native Method)
 java.lang.reflect.Method.invoke(Method.java:507)
 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
 dalvik.system.NativeStart.main(Native Method)

我在我的布局中有以下内容:

FrameLayout
    android:id="@+id/webview_container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_below="@+id/titlebar">
/FrameLayout>

在onCreate()中,我有以下内容:

mWebViewContainer = (FrameLayout)findViewById(R.id.webview_container);
mWebView          = new WebView(getApplicationContext());
mWebViewContainer.addView(mWebView);

mWebView.setWebChromeClient(new WebChromeClient());

我还设置了一个WebViewClient。

我已经验证过mWebView.getWindowToken()会返回非空值。

你有什么想法,为什么会出现这个问题?

编辑: 我进行了更多的实验和查找,但仍然没有解决这个问题。如果我将webview直接放在布局中,一切都正常运行。但我不想这样做,因为我想能够动态地交换webviews。


1
如果您在创建WebView时将“getApplicationContext()”替换为“this”,错误是否仍会发生? - Joakim Berglund
2个回答

13

问题出在这里:

    mWebView.setWebChromeClient(new WebChromeClient());
在您离开活动之后,WebChromeClient中的一些回调有可能尝试在容器活动已被销毁时打开对话框。
这是我使用的一个解决方法,只需在activity的onDestroy()中添加mWebView.destroy()即可。
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mWebView != null)
            mWebView.destroy();
    }

9

创建WebView时,您当前使用的是应用程序的上下文。您应该使用Activity的上下文。为解决该问题,请在创建WebView时将getApplicationContext()替换为this


这应该是注释吧?我认为你有声望可以添加注释。在有人投反对票之前,移动到注释中。 - kosa
没错,没错。我编辑了答案,因为我认为这可能会解决问题。 - Joakim Berglund
不幸的是,这并没有解决问题。即使使用“this”,仍然会发生相同的崩溃。 - Zack Foster
1
即使通过XML创建了webview,我仍然遇到了相同的问题。因此,这似乎不是解决方案... - Tom Susel

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