Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android BadTokenException when using a WebView Container

So I followed a post on avoiding WebView memory leaks, which suggests to use a webview container and then programmatically add/remove the webview from the container in activity codes: Memory leak in WebView

However, I hit the following crash when clicking on an html element which prompts a list of options to select, (e.g. date/Month drop down menu)

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)

I have the following in my layout:

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

I have the following in onCreate():

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

mWebView.setWebChromeClient(new WebChromeClient());

I also set a WebViewClient.

I have verified that mWebView.getWindowToken() does return a non-null value.

Any ideas as to why this issue might be happening?

Edit: I've done some more experimenting and looking around, but still haven't solved this issue. Everything functions fine if I put the webview directly in the layout itself. But I don't want to do that because I want to be able to dynamically swap webviews.

like image 331
Zack Foster Avatar asked Feb 07 '12 20:02

Zack Foster


2 Answers

The problem is here:

    mWebView.setWebChromeClient(new WebChromeClient());

after you have left the activity, there're chances that some callbacks in WebChromeClient will try to open dialogs while the container activity has been destroyed.
Here is one solution that works for me, just add mWebView.destroy() in your activity's onDestroy()

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mWebView != null)
            mWebView.destroy();
    }
like image 55
Bolton Avatar answered Sep 21 '22 09:09

Bolton


When you create the WebView you are currently using the context of the application. You should be using the context of the Activity. To solve the problem, replace getApplicationContext() with this when you create the WebView.

like image 42
Joakim Berglund Avatar answered Sep 21 '22 09:09

Joakim Berglund