2012-10-14 9 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調用...

相關問題