thread example create android multithreading webview

android - example - Los hilos de WebView nunca se detienen(WebViewCoreThread, CookieSyncManager, http[0-3])



threadpool android (10)

Uso WebView para mostrar contenido de Internet en una de las actividades de nuestra aplicación.
¡El problema es que cuando el usuario se desconecta de esta actividad, los hilos de WebView siguen funcionando!
Los hilos problemáticos son:

Thread [<17> WebViewCoreThread] (Running) Thread [<25> CookieSyncManager] (Running) Thread [<19> http0] (Running) Thread [<29> http1] (Running) Thread [<31> http2] (Running) Thread [<33> http3] (Running)

Pausando cada uno de estos hilos, y verificando qué está ocupado:

Thread [<17> WebViewCoreThread] (Suspended) Object.wait(long, int) line: not available [native method] MessageQueue(Object).wait() line: 288 MessageQueue.next() line: 148 Looper.loop() line: 110 WebViewCore$WebCoreThread.run() line: 471 Thread.run() line: 1060 Thread [<25> CookieSyncManager] (Suspended) Object.wait(long, int) line: not available [native method] MessageQueue(Object).wait(long) line: 326 MessageQueue.next() line: 144 Looper.loop() line: 110 CookieSyncManager(WebSyncManager).run() line: 90 Thread.run() line: 1060 Thread [<19> http0] (Suspended) Object.wait(long, int) line: not available [native method] RequestQueue(Object).wait() line: 288 ConnectionThread.run() line: 93

Me pregunto cómo puedo decirle al Looper en cada uno de esos hilos que se vaya.

Intenté llamar a webView.destroy() en el método webView.destroy() de la actividad, pero no tuvo ninguna influencia.
Cuando deshabilito la llamada para abrir una página web en webView ( webView.loadUrl(...) ), esos subprocesos, naturalmente, no se inician y, por lo tanto, no permanecen encendidos después de abandonar la actividad.

¿Alguna idea sobre cómo puedo hacer que los hilos de WebView detengan después de dejar su actividad?


¿Qué pasa con WebView.destroy ()? Eso parece ser limpiarme las cosas o hacerme las cosas sin hacer llamadas de reflejo funky.


Debería poder detener / reanudar estos hilos llamando a onPause / onResume en la vista web.

Sin embargo, están ocultos, por lo que tendrá que hacerlo a través de la reflexión. El siguiente código funcionó para mí:

Class.forName("android.webkit.WebView").getMethod("onPause", (Class[]) null).invoke(webView, (Object[]) null);

Donde webView es la instancia de WebView.

Ver también: http://code.google.com/p/android/issues/detail?id=10282


Definir un método:

private void hiddenWebViewMethod(String state){ if( webView != null ){ try { Method method = WebView.class.getMethod(state); method.invoke(webView); } catch (Exception e) { Log.e("TAG", "Exception: " + e.toString()); webView.loadData("", "text/html", "utf-8"); } } }

luego llama a hiddenWebViewMethod("onPause"); para detener la carga y hiddenWebViewMethod("onResume"); Resumir.


Eche un vistazo a este hilo de andev.org ( problema WebViewCoreThread ).

Ver la respuesta ... Re: WebViewCoreThread problem - Postby potatoho

2) Para pausar el flash, debe llamar a los métodos ocultos WebView.onPause () / WebView.onResume ().

3) Para pausar WebViewCoreThread, usa WebView.pauseTimers () / WebView.resumeTimers ().

Salté el onPause / onResume, pero implementé webView.pauseTimers() y webView.resumeTimers() y al menos detiene el sangrado de la CPU.

También agregué CookieSyncManager.getInstance().stopSync() / startSync a mi onPause / onResume también.


En realidad, al utilizar webView.destroy(), onPause(), clear**() no puede detener Webcore y sus hilos relacionados todavía.

Prácticamente, una forma ideal es establecer que la actividad en la que reside WebView sea un proceso independiente, de modo que cuando la actividad finalice, todos los hilos, incluido Webcore, se destruirán.

Esa es la forma en que he empleado. Quizás también sea útil para ti.


Gracias por esta información, tuve este problema pausando sonidos en mi swf en webView cuando presiono el botón de bloqueo en el teléfono, onPause y onResume todavía reproduce mi swf cuando presiono el botón de desbloqueo pero la actividad aún no está visible, te sugiero colóquelos en onWindowFocusChanged si desea pausar y reanudar la reproducción de sonidos swf en webView

@Override public void onWindowFocusChanged(boolean hasFocus) { gameView = (WebView) findViewById(R.id.gameView); // TODO Auto-generated method stub if (hasFocus) { try { Class.forName("android.webkit.WebView") .getMethod("onResume", (Class[]) null) .invoke(gameView, (Object[]) null); } catch (Exception e) { } gameView.resumeTimers(); gameView.loadUrl("javascript:setflashfocus()"); } else { try { Class.forName("android.webkit.WebView") .getMethod("onPause", (Class[]) null) .invoke(gameView, (Object[]) null); } catch (Exception e) { } gameView.pauseTimers(); } super.onWindowFocusChanged(hasFocus); }


Las soluciones anteriores me fallaron en Samsung Galaxy S con Android 2.3.3. Pero logré el éxito probando la siguiente solución:

webview.loadUrl("file:///android_asset/nonexistent.html");

Estoy forzando que la vista web cargue un archivo html no existente. Esto parece estar forzando a la vista web a limpiar las cosas.


Mi solución, en la clase extendida de webview (probado en android 2.2, andriod 2.3, android 3.1):

private boolean is_gone = false; public void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); if (visibility == View.GONE) { try { WebView.class.getMethod("onPause").invoke(this); //stop flash } catch (Exception e) {} this.pauseTimers(); this.is_gone = true; } else if (visibility == View.VISIBLE) { try { WebView.class.getMethod("onResume").invoke(this); //resume flash } catch (Exception e) {} this.resumeTimers(); this.is_gone = false; } } public void onDetachedFromWindow() { //this will be trigger when back key pressed, not when home key pressed if (this.is_gone) { try { this.destroy(); } catch (Exception e) {} } }


Tuve que llamar a Destroy de WebView para limpiar la memoria específicamente para la vista web. Estaba cargando flash y estaba matando mi aplicación cuando volvemos a esta actividad con una vista web. Flash te comerá vivo si no destruyes tu WebView CADA VEZ que termines con ella.


Una solución limpia y fácil que hace el trabajo:

@Override public void onPause() { super.onPause(); webView.onPause(); webView.pauseTimers(); //careful with this! Pauses all layout, parsing, and JavaScript timers for all WebViews. } @Override public void onResume() { super.onResume(); webView.onResume(); webView.resumeTimers(); } @Override public void onDestroy() { super.onDestroy(); parentViewGroup.removeAllViews(); //the viewgroup the webview is attached to webView.loadUrl("about:blank"); webView.stopLoading(); webView.setWebChromeClient(null); webView.setWebViewClient(null); webView.destroy(); webView = null; }