【问题标题】:Android UnifiedNativeAds causing Memory leaksAndroid UnifiedNativeAds 导致内存泄漏
【发布时间】:2020-10-24 14:55:05
【问题描述】:

我在正确销毁 RecyclerView 中的统一原生广告时遇到了问题。 我正在通过包含已加载广告引用的 AdManager 类加载广告。我的 AdManager 类中还有一个 destroy() 方法,我调用它来销毁调用 RecyclerView 的所有引用广告。 在我的 RecyclerView 适配器中,我还有一个 destroy() 方法,我在其中调用 AdManager 的 destroy() 方法。 我的 Adapter 中的 destroy() 方法在包含 RecyclerView 的 Fragment 的 onDestroyView() 方法中调用。片段位于具有父活动的活动中。 当我回到父活动时,就会发生泄漏。

┬───
│ GC Root: Local variable in native code
│
├─ Bu instance
│    Leaking: NO (PathClassLoader↓ is not leaking)
│    Thread name: 'CleanupReference'
│    ↓ Bu.contextClassLoader
├─ dalvik.system.PathClassLoader instance
│    Leaking: NO (AdManager↓ is not leaking and A ClassLoader is never leaking)
│    ↓ PathClassLoader.runtimeInternalObjects
├─ java.lang.Object[] array
│    Leaking: NO (AdManager↓ is not leaking)
│    ↓ Object[].[92]
├─ com.example.projects.utility.AdManager class
│    Leaking: NO (a class is never leaking)
│    ↓ static AdManager.mInstance
│                       ~~~~~~~~~
├─ com.example.projects.utility.AdManager instance
│    Leaking: UNKNOWN
│    ↓ AdManager.mAdLoader
│                ~~~~~~~~~
├─ com.google.android.gms.ads.AdLoader instance
│    Leaking: UNKNOWN
│    ↓ AdLoader.zzacr
│               ~~~~~
├─ com.google.android.gms.internal.ads.zzcwt instance
│    Leaking: UNKNOWN
│    ↓ zzcwt.zzgpi
│            ~~~~~
├─ com.google.android.gms.internal.ads.zzcxj instance
│    Leaking: UNKNOWN
│    ↓ zzcxj.zzgpz
│            ~~~~~
├─ com.google.android.gms.internal.ads.zzcxr instance
│    Leaking: UNKNOWN
│    ↓ zzcxr.zzgqh
│            ~~~~~    
├─ com.google.android.gms.internal.ads.zzbpi instance
│    Leaking: UNKNOWN
│    ↓ zzbpi.zzfph
│            ~~~~~
├─ com.google.android.gms.internal.ads.zzdod instance
│    Leaking: UNKNOWN
│    ↓ zzdod.zzhfl
│            ~~~~~
├─ com.google.android.gms.internal.ads.zzdtz instance
│    Leaking: UNKNOWN
│    ↓ zzdtz.value
│            ~~~~~
├─ com.google.android.gms.internal.ads.zzbph instance
│    Leaking: UNKNOWN
│    ↓ zzbph.zzfpg
│            ~~~~~
├─ java.util.ArrayList instance
│    Leaking: UNKNOWN
│    ↓ ArrayList.elementData
│                ~~~~~~~~~~~
├─ java.lang.Object[] array
│    Leaking: UNKNOWN
│    ↓ Object[].[0]
│               ~~~
├─ com.google.android.gms.internal.ads.zzdul instance
│    Leaking: UNKNOWN
│    ↓ zzdul.value
│            ~~~~~
├─ com.google.android.gms.internal.ads.zzccd instance
│    Leaking: UNKNOWN
│    ↓ zzccd.zzfwg
│            ~~~~~
├─ com.google.android.gms.internal.ads.zzcde instance
│    Leaking: UNKNOWN
│    ↓ zzcde.zzbnm
│            ~~~~~
├─ android.widget.FrameLayout instance
│    Leaking: YES (View.mContext references a destroyed activity)
│    mContext instance of com.example.projects.ui.DynamicActivity with mDestroyed = true
│    View#mParent is set
│    View#mAttachInfo is null (view detached)
│    View.mWindowAttachCount = 1
│    ↓ FrameLayout.mContext
╰→ com.example.projects.ui.DynamicActivity instance
Leaking: YES (ObjectWatcher was watching this because com.example.projects.ui.DynamicActivity                                 
received Activity#onDestroy() callback and Activity#mDestroyed is true)

更准确地说,当我的统一原生广告视图位于 RecyclerView Viewholder 中时,我如何才能或更准确地说何时销毁它。我不是指广告对象本身,我是指来自 xml 文件的广告视图。

【问题讨论】:

    标签: android android-recyclerview memory-leaks leakcanary


    【解决方案1】:

    来自官方文档:

    确保在您的 Activity 的 onDestroy() 方法。

    在您的 onNativeAdLoaded 回调中,确保销毁任何现有的 将被取消引用的原生广告。

    另一个关键检查是活动是否被销毁,如果是,则调用 在返回的广告上销毁()并立即返回:

    final AdLoader adLoader = new AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
            .forNativeAd(new NativeAd.OnNativeAdLoadedListener() {
        @Override
        public void onNativeAdLoaded(NativeAd ad) {
            // If this callback occurs after the activity is destroyed, you
            // must call destroy and return or you may get a memory leak.
            // Note `isDestroyed()` is a method on Activity.
            if (isDestroyed()) {
                ad.destroy();
                return;
            }
            ...
        }
    }).build();
    

    【讨论】:

      【解决方案2】:

      您应该在活动/片段被销毁之前销毁广告 活动中

      @Override
          public void onDestroy() {
              if (nativeAd != null) {
                  nativeAd.destroy();
              }
              super.onDestroy();
          }
      

      在片段中

      @Override
          public void onDestroyView() {
              if (nativeAd != null) {
                  nativeAd.destroy();
              }
              super.onDestroyView();
          }
      

      【讨论】:

      • 不工作。我有同样的问题。即使我从其父级中删除广告视图,泄漏仍然存在。不知道怎么回事。
      猜你喜欢
      • 2011-09-03
      • 2017-11-24
      • 1970-01-01
      • 2015-07-06
      • 2014-06-07
      • 2013-11-20
      • 2011-10-28
      • 2016-01-18
      • 2012-12-13
      相关资源
      最近更新 更多