2012-02-07 8 views
6

Così ho seguito un post su evitando perdite di memoria WebView, che suggerisce di utilizzare un contenitore webview e quindi programmazione aggiungere/rimuovere il WebView dal contenitore in codici di attività: Memory leak in WebViewAndroid BadTokenException quando si utilizza un WebView contenitore

Tuttavia , mi ha colpito l'incidente seguente quando si fa clic su un elemento html che richiede un elenco di opzioni per selezionare, (menu a discesa per esempio data/mese)

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) 

ho la seguente nel mio layout:

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

Ho il seguente in onCreate():

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

mWebView.setWebChromeClient(new WebChromeClient()); 

Ho anche impostato un WebViewClient.

Ho verificato che mWebView.getWindowToken() restituisce un valore non nullo.

Qualche idea sul motivo per cui questo problema potrebbe verificarsi?

Modifica: Ho fatto altri esperimenti e mi sono guardato intorno, ma non ho ancora risolto questo problema. Tutto funziona bene se metto la webview direttamente nel layout stesso. Ma non voglio farlo perché voglio essere in grado di scambiare dinamicamente le visualizzazioni web.

+1

fa ancora verificarsi l'errore se si sostituisce "getApplicationContext()" con "questo" quando si crea la WebView? –

risposta

9

Quando si crea la WebView si sta attualmente utilizzando il contesto dell'applicazione. Dovresti utilizzare il contesto dell'attività. Per risolvere il problema, è necessario sostituire getApplicationContext() con this durante la creazione di WebView.

+0

non dovrebbe essere un commento? Penso che tu abbia la reputazione di aggiungere commenti. Passa al commento prima che qualcuno possa votare. – kosa

+0

Vero, vero. Modificato la risposta in quanto penso che questo potrebbe risolvere il problema, però. –

+0

Sfortunatamente questo non risolve il problema. Lo stesso crash si verifica anche quando si utilizza "questo" –

13

Il problema è qui:

mWebView.setWebChromeClient(new WebChromeClient()); 

dopo aver lasciato l'attività, ci stiamo probabilità che alcuni callback in WebChromeClient tenterà di aprire finestre di dialogo durante l'attività del contenitore è stata distrutta.
Qui è una soluzione che funziona per me, è sufficiente aggiungere mWebView.destroy() in OnDestroy della vostra attività()

@Override 
    public void onDestroy() { 
     super.onDestroy(); 
     if (mWebView != null) 
      mWebView.destroy(); 
    } 
Problemi correlati