Yo uso un WebView para mostrar algún contenido de internet en uno de nuestros aplicación
Actividades.

El problema es que cuando el usuario cambia de esta actividad,
WebView subprocesos de seguir corriendo!

La problemática de los subprocesos 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)

Pausa cada uno de estos hilos, y la comprobación de lo que está ocupada haciendo:

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 saber el Looper en cada uno de esos temas para dejar de fumar.

He intentado llamar webView.destroy() en la actividad del onPause() método,
pero no tenía ninguna influencia.

Cuando me desactivar la llamada para la apertura de una página web en el webView
( webView.loadUrl(...) ), aquellos hilos que, naturalmente, no se han iniciado, y
por lo tanto, no se quedan en después de salir de la actividad.

Alguna idea de cómo puedo hacer WebView‘s hilos de parada después de salir de
su actividad?

  • «Alguna idea de cómo puedo hacer WebView subprocesos de parada después de salir de su actividad?» ¿Por qué te importa? Qué daño está causando?
  • He estado tratando de evitar tener extra subprocesos que se ejecutan, la celebración de los recursos en la memoria y (posiblemente) la adición de más recursos de la cpu de la programación de las ranuras. Estás diciendo que no tendrá ninguna influencia en el rendimiento ni a los recursos?
  • mismo aquí. WebView hilos drena la batería demasiado.

10 Comentarios

  1. 40

    Usted debe ser capaz de detener /reanudar estos hilos llamando a la onPause /onResume en el webview.

    Esos son, sin embargo, oculta, 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.

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

    • Gracias por la respuesta. Como el informe de error en la url proporcionada dice, podría funcionar, pero «se siente un poco sucio». Supongo que por ahora es la mejor respuesta a esta pregunta.
    • ¿Podría ser más claro por favor donde tengo que agregar este código.
    • Así, tomando la pregunta original en cuenta, me gustaría anular la actividad principal de los métodos de onPause y onResume y llamar desde allí.
    • Por favor, tenga en cuenta que esto no funciona si el WebView tiene un Javascript temporizador de algún tipo de ejecutar.
  2. 16

    Mi solución, en la extensión de la webview clase(probado en android 2.2, android 2.3 y superior, 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) {}
         }
     }
    • Funciona muy bien! lo que realmente hizo que mi app mucho más rápido.
    • Una advertencia a tener en cuenta. Me di cuenta de que si se llama a este.pauseTimers(), todos los WebView se está en pausa, no sólo la instancia de su llamada de este tipo. Esto fue en Adroid 4.0.4
    • Gracias por Weenings de pruebas en Andrdoid 4.0.4
    • Funciona. Usted mecer tio
    • Esto es de trabajo. Permítanme repetir: ESTE, ES decir, TRABAJANDO. Otra solución no estaban lo suficientemente bueno, porque si usted tenía un webview en un fragmento, si has perdido el apego, que no tienen acceso a la rosca más. Pero esto está funcionando a la perfección. Muchas gracias.
    • Bedst solución por el momento 🙂

  3. 13

    Una limpieza fácil solución 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;
    }
    • onPause y onResume de webview no eran accesibles antes de la API 11.
    • Esto funcionó excelente, para mi 4.4.2 aplicación, aunque i havnt han descubierto lo que «parentViewGroup.removeAllViews (); «, aunque «javaScriptTester.removeAllViews();» que parecía ser aceptado por el ide. así?? y como Ayyappa dijo que se requiere de la api de nivel 11.
    • removeAllViews() limpia las vistas asociadas, tales como el construido en los controles de zoom. Si se muestran cuando vuelva a salir de la actividad, deberá obtener una fuga. Consulte stackoverflow.com/questions/27254570/…
    • Funciona muy bien en mi escenario, thx.
  4. 4

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

    Ver la respuesta… Re: WebViewCoreThread problema – Postby potatoho

    2) Para hacer una pausa flash tienes que llamar a escondidas métodos WebView.onPause() /WebView.onResume().

    3) Para hacer una pausa WebViewCoreThread utilizar WebView.pauseTimers() /WebView.resumeTimers().

    Me he saltado el onPause/onResume, pero he implementado webView.pauseTimers() y webView.resumeTimers() y por lo menos deja la CPU sangrar.

    También he añadido CookieSyncManager.getInstance().stopSync() /startSync a mi onPause/onResume así.

    • Gracias, he encontrado la solución en el blog:En su Actividad onPause usted debe llamar a WebView.onPause() y WebView.pauseTimers(). En su Actividad onResume usted debe llamar a WebView.onResume() y WebView.resumeTimers(). Pero dado que hay un error en el recuento, usted necesita llamar a WebView.resumeTimers() al crear por primera vez el WebView. WebView.clase.getMethod(«onPause»).invoke(webview);
    • webview.pauseTimers();
  5. 2

    Gracias por estos info, he tenido este problema de la pausa de los sonidos en mi swf en webView cuando presione el botón de bloqueo en el teléfono, onPause y onResume todavía juega mi swf cuando presione el botón de desbloqueo, pero la actividad no es todavía visible, le sugiero que coloque estos en onWindowFocusChanged si desea hacer una pausa y reanudar la reproducción de swf sonidos 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);
    }
    • gracias a su ayuda me.
  6. 2

    Lo que acerca de WebView.destroy()? Que parece ser la limpieza de las cosas o de mí sin hacer ningún funky reflexión llamadas.

  7. 1

    De hecho, el uso de webView.destroy(), onPause(), clear**() no puede dejar de Webcore y sus temas relacionados con la todavía.

    Prácticamente, una forma ideal es establecer la actividad donde WebView reside en un proceso independiente, de modo que cuando la actividad se haya terminado, todos los subprocesos incluidos Webcore será destruido.

    Que es la forma en que he empleado. Tal vez también es útil para usted.

  8. 0

    Tuve que llamar onDestroy de WebView para borrar la memoria específicamente para el webview. Yo estaba cargando flash y fue matando a mi aplicación cuando volvemos a esta actividad con un webview. Flash va a comer vivo si no destruir su WebView CADA VEZ que haya terminado con él.

  9. 0

    Las soluciones anteriores no para mí en el Samsung Galaxy S con Android 2.3.3.
    Pero he hecho el éxito de tratar el siguiente solución:

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

    Estoy obligando a que el webview para cargar un inexistente archivo html. Esto parece estar forzando a la webview para limpiar las cosas.

  10. 0

    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");
                }
            }
        }

    a continuación, llamar a hiddenWebViewMethod("onPause"); para detener la carga, y hiddenWebViewMethod("onResume"); para reanudar.

Dejar respuesta

Please enter your comment!
Please enter your name here