android 我的插播广告导致了内存泄漏?

cgvd09ve  于 2023-06-28  发布在  Android
关注(0)|答案(3)|浏览(148)

我也试过使用ApplicationContext,但由于某种原因它仍然泄漏。
在AdMob(SDK 7.0)for Android上发现了关于AdActivity泄漏的类似帖子,但没有答案。
还尝试在onDestroy()中将adlistener和广告设置为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泄漏跟踪

┬───
    │ 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
sgtfey8w

sgtfey8w1#

根据InterstitialAd Docs:
单个InterstitialAd对象可用于在Activity的生命周期内请求和显示多个插播广告,因此您只需构造一次
再次查看代码后,我注意到每次调用refreshInterstitial()方法时都要重新构造mInterstitialAd。但是根据上面的文档,你应该在onCreate()期间只构造一次mInterstitialAd
在您的例子中,**内存泄漏的主要原因是:**您仍然有一个活动的侦听器(绑定到Activity寿命),但您使用另一个侦听器重新构建了一个新的InterstitialAd示例。
因此,解决方案是重用InterstitialAd示例及其侦听器,而无需重新分配。我建议将refreshInterstitial()方法简化为:

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

然后将mInterstitialAd赋值给onCreate()。此解决方案与您可以在此处找到的解决方案类似。

kzmpq1sx

kzmpq1sx2#

这是为我工作:(在ActivityMain()中):

MobileAds.initialize(WeakReference(applicationContext).get()){}

在片段中:

adView= AdView(WeakReference(requireActivity().application).get())

LeakCanary显示:
==================================堆分析结果=====================================================================================================================================================================================================================

z9smfwbn

z9smfwbn3#

我在插播广告中也遇到了同样的问题,通过将FullScreenContentCallback在其所有重写方法中设置为null来解决。

interstitial.setFullScreenContentCallback(new FullScreenContentCallback() {
        @Override
        public void onAdDismissedFullScreenContent() {
            super.onAdDismissedFullScreenContent();
            
            interstitial.setFullScreenContentCallback(null);}}

相关问题