WebViewCoreThread utilizado por admob AdView utiliza CPU alta incluso cuando la actividad principal está en pausa

Estoy utilizando Google Admob SDK v6.1.0 (https://developers.google.com/mobile-ads-sdk/download), e instanciar el com.google.ads.AdView mediante programación (no en XML) y agregar en un LinearLayout, dinámicamente en mi Actividad.

Uno de mis usuarios informó que cuando hacen clic en el botón de inicio mientras en mi actividad (con el fin de fondo), que comienzan a ver el uso de la CPU de alta procedentes de mi aplicación. Pude reproducir esto en una plataforma de Jellybean, y noté que la fuente para el alto uso de la CPU era WebViewCoreThread.

Mi actividad no utiliza ningún WebView en absoluto, pero pude pasar por la inicialización de mi actividad y noté que este WebViewCoreThread se inicia cuando instancio el objeto AdView de AdMob. Como estado en las referencias de AdMob, llamo a destroy () en este AdView en el método onDestroy () de mi actividad. Y aso cambió mi código para llamar a AdView.onDestroy () en mi método onPause (). Pero nada parece estar causando la parada de WebViewCoreThread. Supongo que estoy bien si ese hilo se mete. Pero si empiezo mi Actividad varias veces una y otra vez, este hilo comienza a usar entre 8 y 25% de mi CPU, incluso mi actividad no está en primer plano.

Me di cuenta de algunos otros usuarios diciendo que debe llamar a WebView.onPause () como una acción correctiva. (http://stackoverflow.com/questions/2040963/webview-threads-never-stop-webviewcorethread-cookiesyncmanager-http0-3) Pero esto no es directamente posible para mí, ya que mi vista web es creada por AdView de AdMob. También cambié mi código para llamar .removeAllViews () para el objeto Contenedor LinearLayout de Adtm AdView, y luego llamar a System.gc () para forzar la recolección de basura, pero nada parece matar mi WebViewCoreThread y eventualmente comienza a consumir la CPU hasta que fuerza -mata el proceso de mi aplicación.

¿Alguna pista sobre por qué AdMob está haciendo esto, y cómo puedo forzar a matar a este hilo?

Estoy adjuntando una clase que he creado para encapsular la creación y destrucción de AdView. Llamo el método getNewAd () de esta clase en la inicialización de mi actividad. Y llamo a esta clase removeAd () en los métodos onPause () y onDestroy () de mi actividad:

package com.shiprack.client; import com.google.ads.AdRequest; import com.google.ads.AdSize; import com.google.ads.AdView; import com.mobclix.android.sdk.Mobclix; import com.mobclix.android.sdk.MobclixMMABannerXLAdView; import android.app.Activity; import android.view.Gravity; import android.view.ViewGroup.LayoutParams; import android.widget.LinearLayout; public class AdManager { public AdManager(EventLog logger, LinearLayout container, Activity activity) { _container = container; _activity = activity; _eventLogger = logger; } public void setNetwork(int network) { _network = network; } public void getNewAd() { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT); params.gravity = Gravity.CENTER; switch (_network) { case TrackDatabase.AD_NETWORK_ADMOB: { _admobBanner = new AdView(_activity, AdSize.BANNER, "a14dc419375634c"); _container.addView(_admobBanner, params); _admobBanner.loadAd(new AdRequest()); break; } case TrackDatabase.AD_NETWORK_MOBCLIX: { Mobclix.onCreate(_activity); _mobclixBanner = new MobclixMMABannerXLAdView(_activity); _container.addView(_mobclixBanner, params); _mobclixBanner.getAd(); break; } } } public void removeAd() { switch (_network) { case TrackDatabase.AD_NETWORK_ADMOB: { _admobBanner.destroy(); break; } case TrackDatabase.AD_NETWORK_MOBCLIX: { _mobclixBanner.cancelAd(); break; } } _container.removeAllViews(); } private EventLog _eventLogger; private LinearLayout _container; private Activity _activity; private AdView _admobBanner; private MobclixMMABannerXLAdView _mobclixBanner; private int _network; } 

No estoy seguro de si alguien todavía necesita esta información, pero he estado buscando una solución a esto mismo. Aparentemente, AdMob sigue estando defectuoso.

El único problema es que esto detendrá que todas las WebView se ejecuten en segundo plano. Sólo es un problema si la aplicación depende de esto para funcionar.

Añadir a onPause() :

 new WebView(this).pauseTimers(); 

y onResume() :

 new WebView(this).resumeTimers(); 

Esto provino de un empleado de Google que afirma que lo está buscando: https://groups.google.com/d/msg/google-admob-ads-sdk/Qu4G19NFAuI/wcNkoV0AeDUJ

Después de llamar a destroy () en el objeto adView AdView, ahora establezco la referencia a null, que elimina todas las referencias a la AdView, tal vez haciendo que se recoja la basura, y por lo tanto, evitando que WebViewCoreThreads se ejecute indefinidamente. En general, no me gusta este enfoque – este trabajo de limpieza debe ser manejado dentro de la destrucción de AdMob. O en realidad, ni siquiera tendría que llamar a destroy () – se ralentiza mi actividad onPause.

Gran desventaja, sin embargo: muchos de mis usuarios se quejan de la lentitud al presionar la parte posterior o botones de inicio en mi aplicación. Obviamente, esto se debe a que el tiempo se gasta en el método onPause () mientras se llama a admob destroy (). La solución a largo plazo es utilizar Fragments y ActionBar, y no tener que crear varias copias del banner de Admob (una en cada actividad)

PZolee publicado en este tema y una propuesta de solución en su blog: https://pzoleeblogen.wordpress.com/2014/07/08/android-how-to-solve-adview-cpu-consuming/

Investigué esto más (en los comentarios a la entrada del blog se documentan mis luchas) y llegó a la siguiente conclusión:

  1. De hecho, llamar a adView.pause (); no impide que el componente de anuncios de Google consuma CPU aunque la aplicación esté en segundo plano y los anuncios no sean visibles.
  2. Encontrar todas las WebViews dentro de nuestros métodos adView y calling onPause () y onResume () de WevView no resuelve el problema del consumo innecesario de CPU.
  3. Sólo la llamada a los métodos de espera de WebView pauseTimers () y resumeTimers () como el autor de la publicación anterior propone detener el consumo innecesario de CPU.
  4. No es necesario encontrar recursivamente todas las WebViews y llamar a pauseTimers () y resumeTimers () en todas ellas, ya que una de esas llamadas "Pausa (o reanuda) todos los temporizadores de diseño, análisis y JavaScript para todas las WebViews. (dentro de un proceso – g.) "- vea Documentos del componente WebView.
  5. Si utiliza un WebView en cualquier otro lugar de su aplicación, tal vez en otras actividades, debe reanudarTimers () para ello o no funcionará correctamente. Además, tenga en cuenta que un WevView puede ser construido temporalmente y utilizado por algunas funciones de la biblioteca que utiliza en su proyecto, sin que explícitamente saber sobre él. Podría ser, por ejemplo, un aviso para iniciar sesión en algún sitio web, red social, etc. Tal WebView puede no funcionar de nuevo, si se llamó pauseTimers () en su proceso y no los reanudó. USE PRECAUCIÓN Y PRUEBE todo lo que pueda.

Es realmente una lástima que Google y AdMob nos hayan manejado una sorpresa tan desagradable con su componente de anuncios (consumo constante de CPU, incluso si el fondo de la aplicación, ocultar su componente, incluso pausa () con su propia llamada API …

  • Mediación de Admob - ID de editor y ID de mediación
  • Cómo implementar AdView AdView en la aplicación para Android
  • Excepción de seguridad de Admob: denegación de permisos
  • Impedir que AdView se recupere para cada actividad
  • ¿Cuál es el tamaño, en píxeles, de AdSize.BANNER?
  • ¿Cómo especificar adUnitId mediante programación para AdMob?
  • AdView causa pérdida de memoria
  • Parece que no se puede visualizar un ListView y un AdView al mismo tiempo
  • Cómo ocultar / deshabilitar adview admob?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.