2012-10-14 25 views
15

我使用Google Admob SDK v6.1.0(https://developers.google.com/mobile-ads-sdk/download)和我以编程方式(不是以XML格式)实例化com.google.ads.AdView,并在我的Activity中动态地将其添加到LinearLayout中。admob使用的WebViewCoreThread即使在父活动暂停时,AdView仍在使用高CPU

我的一位用户报告说,当他们在我的活动中点击主页按钮时(他们为了背景),他们开始看到来自我的应用程序的高CPU使用率。我能够在Jellybean平台上重现这一点,并注意到高CPU使用率的来源是WebViewCoreThread。

我的活动根本没有使用任何WebViews,但我能够完成我的Activity的初始化,并且注意到当我实例化AdMob AdView对象时,此WebViewCoreThread启动。作为AdMob参考文献中的状态,我在Activity的onDestroy()方法中调用了此AdView上的destroy()。我aso更改我的代码,以在我的onPause()方法中调用AdView.onDestroy()。但是没有任何东西似乎导致WebViewCoreThread停止。我想,如果那条线路停留在附近,我很好。但是如果我一次又一次地开始我的活动,这个线程开始使用CPU的8%到25%之间的任何地方,即使我的活动不在前台。

我注意到一些其他用户说您必须调用WebView.onPause()作为纠正措施。 (http://stackoverflow.com/questions/2040963/webview-threads-never-stop-webviewcorethread-cookiesyncmanager-http0-3)但是这对我来说不是直接可能的,因为我的网络视图是由AdMob的AdView创建的。我还更改了我的代码,以便为mt Admob AdView的容器LinearLayout对象调用.removeAllViews(),然后调用System.gc()强制进行垃圾回收,但似乎没有任何东西会杀死我的WebViewCoreThread,并最终开始吞噬CPU直到我强制 - 杀了我的应用程序的过程。

任何线索为什么AdMob这样做,以及我如何强制这个线程被杀害?

我附上一个我创建的类来封装AdView的创建和销毁。我在我的activity的初始化中调用这个类的getNewAd()方法。我呼吁这个类的removeAd()在我的活动的的onPause()和的onDestroy()方法:

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; 
} 
+0

我想我已经得到了这个工作,但我没有添加这个作为答案,因为我还没有完全相信,在admob AdView对象上调用destroy()之后,我现在将引用设置为null ,它删除了所有对AdView的引用,可能导致垃圾收集,从而避免任何WebViewCoreThreads无限期运行。总的来说,我不喜欢这种方法 - 这种清理工作应该在AdMob destroy中处理。或者实际上,我甚至不需要调用destroy() - 它让我的活动停下来。 – Shiprack

回答

3

调用destroy()中的AdMob AdView的对象后,我现在设定基准值以零,从而消除所有引用到AdView,可能会导致垃圾收集,从而避免任何WebViewCoreThreads无限期地运行。总的来说,我不喜欢这种方法 - 这种清理工作应该在AdMob销毁中处理。或者实际上,我甚至不需要调用destroy() - 它会减慢我在onPause上的活动。

虽然很大的缺点:当我的应用程序按下后退或主页按钮时,我的很多用户抱怨慢。显然,这是因为在调用admob destroy()时花费在onPause()方法上的时间。长期解决方案是使用Fragments和ActionBar,而不必创建Admob横幅的多个副本(每个活动都有一个副本)

+0

也许火上的admob销毁线程? – stu

10

不确定是否有人仍然需要此信息,但我一直在寻找解决方案对此我自己。显然AdMob仍然存在缺陷。

唯一的问题是,这将阻止所有WebViews在后台运行。只有您的应用依赖于此操作才会出现问题。

添加到onPause()

new WebView(this).pauseTimers(); 

,并onResume()

new WebView(this).resumeTimers(); 

这是来自谷歌的员工谁声称,他们正在寻找到它: https://groups.google.com/d/msg/google-admob-ads-sdk/Qu4G19NFAuI/wcNkoV0AeDUJ

+0

谢谢!我会试试这个。 – Shiprack

+0

希望它有帮助。它为我创造了奇迹,但如果AdView.pause()像它应该那样工作,会更好。 –

+0

这是适用于新版AdMob(包含在Google play服务中)的正确解决方案(也是唯一适用于我的解决方案)。 – Szymon

3

PZolee张贴在此主题和他的博客中提出的解决方案:https://pzoleeblogen.wordpress.com/2014/07/08/android-how-to-solve-adview-cpu-consuming/

我进一步研究这个(在评论的博客文章都记录我的奋斗),并得出如下结论:

  1. 事实上,调用只是adView.pause();即使应用程序处于后台并且广告不可见,也不会阻止Google广告组件使用CPU。
  2. 查找我们的adView中的所有WebView并在它们上调用onPause()和onResume()WevView方法不能解决不必要的CPU消耗问题。
  3. 作为上述文章的作者,只有调用WebView pauseTimers()和resumeTimers()方法才能停止不必要的CPU消耗。
  4. 以递归方式查找所有WebView,并且在所有WebView上调用pauseTimers()和resumeTimers()是不必要的,因为一次调用“为所有WebView暂停(或恢复 - )所有布局,解析和JavaScript计时器。 (在一个过程中 - g。)“ - 请参阅WebView组件文档。
  5. 如果您在应用程序的其他任何地方使用WebView - 也许在其他活动中,您必须为其恢复计时器(),否则它将无法正常工作。另外,请注意,WevView可能会临时构建并用于您在项目中使用的某些库函数,而无需您明确地了解它。它可以是例如提示登录到某个网站,社交网络等。如果您的进程在某个地方调用了pauseTimers()并且您没有恢复它们,则此类WebView可能再次无法正常工作。尽可能使用注意事项和测试。

这真是一个耻辱,谷歌和AdMob的处理我们这样一个讨厌的惊喜与他们的广告组件(恒定的CPU消耗,即使你后台的应用程序,隐藏自己的分量,甚至暂停(),它用自己的API调用...

相关问题