web-dev-qa-db-ja.com

インタースティシャル広告がメモリリークを引き起こしていますか?

私もApplicationContextを使用してみましたが、何らかの理由で依然としてリークします。

この問題に関する同様の投稿がこちらにあります Android向けAdMob(SDK 7.0)でのAdActivityリーク ですが、答えはありません。

また、onDestroy()でadlistenerとadをnullに設定しようとしましたが、運が悪く、それでもアクティビティがリークします。

私のコードはonCreate()で呼び出されます

private void refreshInterstitial(){
        mInterstitialAd = new InterstitialAd(this);
        mInterstitialAd.setAdUnitId("AD_ID");
        mInterstitialAd.loadAd(new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).addTestDevice("877BCC97E130A0DC62B2E5770D854496").build());

        mInterstitialAd.setAdListener(new AdListener() {
            @Override
            public void onAdLoaded() {
                mInterstitialAd.show();
            }
            @Override
            public void onAdClosed() {
            }
        });
}

Leakcanary Leak Trace

 ┬───
    │ GC Root: Global variable in native code
    │
    ├─ mx instance
    │    Leaking: UNKNOWN
    │    ↓ mx.a
    │         ~
    ├─ com.google.Android.gms.ads.internal.webview.w instance
    │    Leaking: UNKNOWN
    │    mContext instance of com.google.Android.gms.ads.internal.webview.ay, not wrapping activity
    │    View#mParent is null
    │    View#mAttachInfo is null (view detached)
    │    View.mWindowAttachCount = 1
    │    ↓ w.a
    │        ~
    ├─ com.google.Android.gms.ads.internal.webview.aa instance
    │    Leaking: YES (View detached and has parent)
    │    mContext instance of com.google.Android.gms.ads.internal.webview.ay, not wrapping activity
    │    View#mParent is set
    │    View#mAttachInfo is null (view detached)
    │    View.mWindowAttachCount = 1
    │    ↓ aa.mListenerInfo
    ├─ Android.view.View$ListenerInfo instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ View$ListenerInfo.mOnClickListener
    ├─ com.google.Android.gms.ads.nonagon.ad.webview.f instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ f.a
    ├─ com.google.Android.gms.ads.nonagon.ad.webview.l instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ l.e
    ├─ com.google.Android.gms.ads.nonagon.ad.event.bs instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ bs.a
    ├─ Java.util.HashMap instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ HashMap.table
    ├─ Java.util.HashMap$Node[] array
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ HashMap$Node[].[1]
    ├─ Java.util.HashMap$Node instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ HashMap$Node.key
    ├─ com.google.Android.gms.ads.nonagon.shim.k instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ k.a
    ├─ com.google.Android.gms.ads.internal.client.ae instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ ae.a
    ├─ com.google.Android.gms.internal.ads.zzuc instance
    │    Leaking: YES (aa↑ is leaking)
    │    ↓ zzuc.zzcbw
    ├─ com.test.Activity$1 instance
    │    Leaking: YES (aa↑ is leaking)
    │    Anonymous subclass of com.google.Android.gms.ads.AdListener
    │    ↓ EqualizerActivity$1.this$0
    ╰→ com.test.Activity instance
    ​     Leaking: YES (ObjectWatcher was watching this because Activity received Activity#onDestroy() callback and Activity#mDestroyed is true)
    ​     key = 40a1eb8e-c9e6-4062-b5f7-053e642e812f
    ​     watchDurationMillis = 5288
    ​     retainedDurationMillis = 258
6
Vince VD

InterstitialAd Docs によると:

単一のInterstitialAdオブジェクトを使用して、アクティビティの有効期間中に複数のインタースティシャル広告をリクエストおよび表示できるため、一度作成するだけで済みます

コードをもう一度調べたところ、refreshInterstitial()メソッドが呼び出されるたびにmInterstitialAdを再構築していることがわかりました。しかし、上記のドキュメントによれば、onCreate()の間に一度だけmInterstitialAdを構築する必要があります。

あなたの場合、メモリリークの主な原因:まだアクティブなリスナーがあり(これはアクティビティの寿命にバインドされています)、新しいものを再構築します別のリスナーを持つInterstitialAdインスタンス。

したがって、解決策は、再割り当てせずにInterstitialAdインスタンスとそのリスナーを再利用することです。 refreshInterstitial()メソッドをこれに簡略化することをお勧めします:

_private void refreshInterstitial() {
    mInterstitialAd.loadAd(new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).addTestDevice("877BCC97E130A0DC62B2E5770D854496").build());
}
_

次に、mInterstitialAd割り当てをonCreate()に配置します。この解決策は、あなたが見つけることができるものと似ています here

2
Harry Timothy