15

私は Google Admob SDK v6.1.0 (https://developers.google.com/mobile-ads-sdk/download) を使用しており、プログラムで (XML ではなく) com.google.ads.AdView をインスタンス化し、追加します。アクティビティで動的に LinearLayout に変換します。

私のユーザーの 1 人が、アクティビティ中に (バックグラウンドにするために) ホーム ボタンをクリックすると、アプリの CPU 使用率が高くなり始めると報告しました。これを Jellybean プラットフォームで再現できたのですが、CPU 使用率が高い原因は WebViewCoreThread であることがわかりました。

私のアクティビティは WebView をまったく使用していませんが、アクティビティの初期化を進めることができ、AdMob AdView オブジェクトをインスタンス化するときにこの WebViewCoreThread が開始されることに気付きました。AdMob のリファレンスにあるように、Activity の onDestroy() メソッドでこの AdView の destroy() を呼び出します。また、onPause() メソッドで AdView.onDestroy() を呼び出すようにコードを変更しました。しかし、何も WebViewCoreThread を停止させているようには見えません。たぶん、そのスレッドが残っていれば大丈夫です。しかし、アクティビティを何度も何度も開始すると、アクティビティがフォアグラウンドになくても、このスレッドは CPU の 8 ~ 25% を使用し始めます。

是正措置として WebView.onPause() を呼び出す必要があると言っている他の数人のユーザーに気付きました。(http://stackoverflow.com/questions/2040963/webview-threads-never-stop-webviewcorethread-cookiesyncmanager-http0-3)しかし、私の Web ビューは AdMob の AdView によって作成されているため、これを直接行うことはできません。また、mt Admob AdView のコンテナ LinearLayout オブジェクトに対して .removeAllViews() を呼び出すようにコードを変更し、次に System.gc() を呼び出してガベージ コレクションを強制しましたが、WebViewCoreThread を強制終了するものはないようで、最終的に強制するまで CPU を使い果たし始めます。 -アプリのプロセスを強制終了します。

AdMob がこれを行っている理由と、このスレッドを強制的に強制終了させる方法を教えてください。

AdView の作成と破棄をカプセル化するために作成したクラスを添付しています。アクティビティの初期化で、このクラスの getNewAd() メソッドを呼び出します。そして、Activity の onPause() メソッドと onDestroy() メソッドで、このクラスの removeAd() を呼び出します。

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;
}
4

3 に答える 3

10

誰かがまだこの情報を必要としているかどうかはわかりませんが、私はこれに対する解決策を自分で探しています. どうやら AdMob にはまだ欠陥があるようです。

唯一の問題は、これによりすべての WebView がバックグラウンドで実行されなくなることです。アプリが動作するためにこれに依存している場合にのみ問題になります。

に追加onPause():

new WebView(this).pauseTimers();

onResume():

new WebView(this).resumeTimers();

これは、調査していると主張する Google の従業員からのものです: https://groups.google.com/d/msg/google-admob-ads-sdk/Qu4G19NFAuI/wcNkoV0AeDUJ

于 2014-03-08T06:43:13.723 に答える
3

admob AdView オブジェクトで destroy() を呼び出した後、参照を null に設定しました。これにより、AdView へのすべての参照が削除され、おそらくガベージ コレクションが発生し、WebViewCoreThreads が無期限に実行されるのを回避できます。全体として、このアプローチは好きではありません。このようなクリーンアップ作業は、AdMob の破棄内で処理する必要があります。または実際には、destroy() を呼び出す必要さえないはずです。これにより、onPause のアクティビティが遅くなります。

ただし、大きな欠点があります。多くのユーザーが、アプリの [戻る] ボタンまたは [ホーム] ボタンを押すと速度が遅いと不満を漏らしています。明らかに、これは admob destroy() の呼び出し中に onPause() メソッドで費やされた時間が原因です。長期的な解決策は、Fragments と ActionBar を使用することです。Admob バナーの複数のコピー (アクティビティごとに 1 つ) を作成する必要はありません。

于 2012-10-23T16:35:30.940 に答える
3

PZolee は、このテーマと提案された解決策を彼のブログに投稿しました: https://pzoleeblogen.wordpress.com/2014/07/08/android-how-to-solve-adview-cpu-using/

私はこれをさらに調査し(ブログ投稿へのコメントで私の苦労が文書化されています)、次の結論に達しました:

  1. 確かに、単に adView.pause(); を呼び出します。アプリがバックグラウンドで広告が表示されていない場合でも、Google 広告コンポーネントによる CPU の消費は停止しません。
  2. adView 内のすべての WebView を検索し、それらに対して onPause() および onResume() WevView メソッドを呼び出しても、不要な CPU 消費の問題は解決されません。
  3. 上記の投稿の著者が提案しているように、WebView の pauseTimers() および resumeTimers() メソッドへの呼び出しのみが、不要な CPU 消費を停止します。
  4. すべての WebView を再帰的に検索し、それらすべてで pauseTimers() および resumeTimers() を呼び出す必要はありません。そのような呼び出しの 1 つで、すべての WebView のすべてのレイアウト、解析、および JavaScript タイマーが一時停止 (または再開 – g.) されるためです。(プロセス内 – g.)」 – WebView コンポーネントのドキュメントを参照してください。
  5. アプリの他の場所 (おそらく他のアクティビティ) で WebView を使用する場合は、resumeTimers() を使用する必要があります。そうしないと、正しく機能しません。また、WebView は一時的に構築され、プロジェクトで使用する一部のライブラリ関数によって、明示的に知らなくても使用される可能性があることに注意してください。たとえば、Web サイトやソーシャル ネットワークなどへのログインを促すメッセージなどです。プロセスのどこかで pauseTimers() が呼び出され、それらを再開しなかった場合、このような WebView は正しく機能しない可能性があります。注意を払い、できる限りテストしてください。

Google と AdMob が広告コンポーネントでこのような厄介な驚きを処理したことは本当に残念です (アプリをバックグラウンドで実行したり、コンポーネントを非表示にしたり、独自の API 呼び出しで一時停止() したりしても、一定の CPU 消費が発生します...</p>

于 2015-01-29T16:17:31.413 に答える