2012-10-14 4 views
15

Google Admob SDK v6.1.0 (https://developers.google.com/mobile-ads-sdk/download)을 사용하고 있습니다. 프로그래밍 방식으로 com.google.ads.AdView를 인스턴스화하고 (XML이 아닌) 내 Activity에서 동적으로 LinearLayout에 추가합니다.admView에서 사용하는 WebViewCoreThread 상위 활동이 일시 중지 된 경우에도 AdView가 높은 CPU를 사용합니다.

사용자 중 한 명이 내 활동 (배경 사용) 중에 '홈'버튼을 클릭하면 내 응용 프로그램에서 높은 CPU 사용량이 발생하는 것으로 나타났습니다. 나는 Jellybean 플랫폼에서 이것을 재현 할 수 있었고 CPU 사용량이 많은 소스가 WebViewCoreThread라는 것을 알게되었습니다.

내 활동에 WebView가 전혀 사용되지 않았지만 활동의 초기화를 단계별로 수행 할 수 있었으며 AdMob AdView 객체를 인스턴스화 할 때이 WebViewCoreThread가 시작된다는 사실을 알게되었습니다. AdMob의 참조 상태로,이 AdView에서 내 Activity의 onDestroy() 메소드에서 destroy()를 호출합니다. 그리고 내 onPause() 메소드에서 AdView.onDestroy()를 호출하도록 코드를 변경했습니다. 그러나 WebViewCoreThread가 멈추는 원인은없는 것 같습니다. 나는 그 스레드가 주위에 붙어 있다면 괜찮아요. 하지만 여러 번 여러 번 활동을 시작하면이 스레드는 내 CPU의 8 ~ 25 % 사이에서 아무 곳이나 사용하기 시작합니다. 심지어 내 활동이 포 그라운드에 있지 않습니다.

다른 몇 명의 사용자가 WebView.onPause()를 시정 조치로 호출해야한다는 것을 알게되었습니다. (http://stackoverflow.com/questions/2040963/webview-threads-never-stop-webviewcorethread-cookiesyncmanager-http0-3) 내 웹보기가 AdMob의 AdView에 의해 만들어지기 때문에 이것이 가능하지 않습니다. 또한 Admob AdView의 컨테이너 LinearLayout 객체에 대해 .removeAllViews()를 호출 한 다음 가비지 수집을 강제 실행하기 위해 System.gc()를 호출했지만 내 WebViewCoreThread를 죽이는 것으로 보이지 않으며 결국 강제로 종료 될 때까지 CPU를 먹기 시작합니다. 내 애플 리케이션의 프로세스를 죽일.

AdMob에서이 작업을 수행하는 단서와 내가이 스레드를 강제로 강제 종료 할 수있는 방법은 무엇입니까?

AdView 생성 및 삭제를 캡슐화하기 위해 만든 클래스를 첨부하고 있습니다. 내 활동 초기화에서이 클래스의 getNewAd() 메소드를 호출한다. 그리고 내가) (내 활동의 onPause() 및들의 OnDestroy에서 방법이 클래스의 removeAd()를 호출 다음 몹의 AdView가 객체에() 파괴 호출 한 후

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에 대한 모든 참조를 제거하여 가비지 수집을 유발하여 모든 WebViewCoreThread가 무기한 실행되는 것을 방지합니다. 전반적으로이 방법은 마음에 들지 않습니다. 이러한 정리 작업은 AdMob 파괴 내에서 처리되어야합니다. 또는 실제로, 나는 destroy()를 호출 할 필요조차 없다. 내 활동을 멈 춥니 다. – Shiprack

답변

3

을, 지금 모든 참조를 제거 참조를 null로 설정 AdView에 가비지 수집을 유발하여 WebViewCoreThread가 무한대로 실행되는 것을 방지 할 수 있습니다. 전반적으로이 접근 방식이 맘에 들지 않습니다. 이러한 정리 작업은 AdMob 파괴 내에서 처리되어야합니다. 또는 실제로, 나는 destroy()를 호출 할 필요조차하지 않아야합니다 - 내 활동 onPause의 속도를 늦 춥니 다.

큰 단점 : 많은 내 사용자가 내 앱에서 뒤로 또는 홈 버튼을 누르면 느려지는 경우가 있습니다. 분명히 이것은 admob destroy()를 호출하는 동안 onPause() 메서드에서 시간이 소비 되었기 때문입니다. 장기적인 해결책은 Fragments 및 ActionBar를 사용하고 Admob 배너 (여러 활동에 하나씩)를 여러 개 만들 필요가 없습니다.

+0

스레드에서 admob을 삭제할 수 있습니까? – stu

10

아직이 정보가 필요하지만 솔루션을 찾고 있는지 확실하지 않습니다. 이 자신에게. AdMob에는 여전히 결함이있는 것으로 보입니다.

유일한 문제는 모든 WebView가 백그라운드에서 실행되는 것을 중지합니다. 응용 프로그램이 작동하는 데 달려있는 경우에만 문제입니다.

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. Google의 adView 내에있는 모든 WebView를 찾고 onPause() 및 onResume() WevView 메서드를 호출해도 불필요한 CPU 소비 문제는 해결되지 않습니다.
  3. 위 게시물의 제안자 인 WebView pauseTimers() 및 resumeTimers() 메서드 호출 만 불필요한 CPU 소비를 중지합니다.
  4. 모든 WebView를 재귀 적으로 찾아서 모든 호출에 대해 pauseTimers() 및 resumeTimers()를 호출하는 것은 불필요합니다. 이러한 호출은 "모든 WebView의 모든 레이아웃, 구문 분석 및 JavaScript 타이머를 일시 중지 (또는 재개)합니다. (프로세스 내에서 - g.) "- WebView 구성 요소 문서를 참조하십시오.
  5. 다른 곳에서 WebView를 사용하는 경우 다른 곳에서 WebView를 사용하는 경우 Timer()를 다시 시작해야합니다. 그렇지 않으면 제대로 작동하지 않습니다. 또한 WevView는 사용자가 명시 적으로 알지 못하는 사이에 프로젝트에서 사용하는 일부 라이브러리 함수에 의해 임시로 생성되고 사용될 수 있습니다. 예를 들어 일부 웹 사이트, 소셜 네트워크 등에 로그인하라는 메시지가 표시됩니다. pauseTimers()가 프로세스에서 어딘가에서 호출되어 다시 시작하지 않으면 이러한 WebView가 다시 제대로 작동하지 않을 수 있습니다. 주의와 테스트는 가능한 한 모두 사용하십시오. 구글과 AdMob에서 자신의 API 호출로 (상수 CPU 소비하면,도 (일시 정지, 자신의 구성 요소를 응용 프로그램 숨기기 배경에도)을 자신의 광고 구성 요소와 함께 우리에게 그런 불쾌한 놀라움을 처리하는 것을

정말 부끄러운, ...