Android升级广告库后内存泄漏

问题描述 投票:0回答:1

今天我把广告库升级为:

implementation 'com.google.android.gms:play-services-ads:21.5.0'

我只使用插页式广告。

现在,我得到了 Leak Canary 检测到的以下内存泄漏。

我正在销毁 Activity 以及所有相关的广告对象,例如将它们设置为 null,将侦听器设置为 null,setFullScreenContentCallback(null) 等

┬───
│ GC Root: Input or output parameters in native code
│
├─ android.os.MessageQueue instance
│    Leaking: NO (MessageQueue#mQuitting is false)
│    HandlerThread: "ExoPlayerImplInternal:Handler"
│    ↓ MessageQueue[0]
│                  ~~~
├─ android.os.Message instance
│    Leaking: UNKNOWN
│    Retaining 2.5 MB in 605 objects
│    Message.what = 2
│    Message.when = 507477121 (661 ms after heap dump)
│    Message.obj = null
│    Message.callback = null
│    Message.target = instance @348531240 of android.os.Handler
│    ↓ Message.target
│              ~~~~~~
├─ android.os.Handler instance
│    Leaking: UNKNOWN
│    Retaining 2.5 MB in 604 objects
│    ↓ Handler.mCallback
│              ~~~~~~~~~
├─ com.google.android.gms.internal.ads.zzatb instance
│    Leaking: UNKNOWN
│    Retaining 2.5 MB in 603 objects
│    ↓ zzatb.zzm
│            ~~~
├─ com.google.android.gms.internal.ads.zzaup instance
│    Leaking: UNKNOWN
│    Retaining 22.1 kB in 81 objects
│    ↓ zzaup.zzb
│            ~~~
├─ com.google.android.gms.internal.ads.zzatz instance
│    Leaking: UNKNOWN
│    Retaining 16 B in 1 objects
│    ↓ zzatz.zzb
│            ~~~
├─ com.google.android.gms.internal.ads.zzclf instance
│    Leaking: UNKNOWN
│    Retaining 346 B in 10 objects
│    zzd instance of com.google.android.gms.internal.ads.zzcpc, wrapping
│    androidx.multidex.MultiDexApplication
│    ↓ zzclf.zzd
│            ~~~
├─ com.google.android.gms.internal.ads.zzcpc instance
│    Leaking: UNKNOWN
│    Retaining 24 B in 1 objects
│    zza instance of com.xxxxx.xxxxx.CreateCardsActivity with
│    mDestroyed = true
│    zzb instance of androidx.multidex.MultiDexApplication
│    zzc instance of com.xxxxx.xxxxx.CreateCardsActivity with
│    mDestroyed = true
│    mBase instance of androidx.multidex.MultiDexApplication
│    zzcpc wraps an Application context
│    ↓ zzcpc.zza
│            ~~~
╰→ com.xxxx.xxxxxx.CreateCardsActivity instance
​     Leaking: YES (ObjectWatcher was watching this because 
     xxxx.xxxxx.CreateCardsActivity received Activity#onDestroy() callback and
​     Activity#mDestroyed is true)
​     Retaining 8.4 kB in 204 objects
​     key = 433e4c0b-dd8e-4321-a496-8a5a5542d28e
​     watchDurationMillis = 428997
​     retainedDurationMillis = 423991
​     mApplication instance of androidx.multidex.MultiDexApplication
​     mBase instance of androidx.appcompat.view.ContextThemeWrapper

METADATA

Build.VERSION.SDK_INT: 28
Build.MANUFACTURER: BLU
LeakCanary version: 2.10
App process name: com.xxx.xxxx
Class count: 20438
Instance count: 386631
Primitive array count: 252937
Object array count: 46275
Thread count: 148
Heap total bytes: 39734117
Bitmap count: 52
Bitmap total bytes: 29096284
Large bitmap count: 0
Large bitmap total bytes: 0
Db 1: open /com.google.android.
datatransport.events
Db 2: closed google_app_measurement_local.db
Db 3: open androidx.work.workdb
Stats: LruCache[maxSize=3000,hits=182820,misses=342787,hitRate=34%]
RandomAccess[bytes=16217423,reads=342787,travel=94405937828,range=40656354,size=
56429010]
Analysis duration: 149315 ms

这就是我在 OnCreate() 中设置 fullScreenContentCallback 的方式:

           FullScreenContentCallback fullScreenContentCallback = new FullScreenContentCallback() {
                @Override
                public void onAdDismissedFullScreenContent() {
                    mAdManagerInterstitialAd.setFullScreenContentCallback(null);

                    mAdManagerInterstitialAd = null;
                }
            };

这是我加载广告的方式:

AdManagerAdRequest adRequest = new AdManagerAdRequest.Builder().build();

            AdManagerInterstitialAd.load(this,getResources().getString(R.string.interstitial_ad_unit_id), adRequest,
                    new AdManagerInterstitialAdLoadCallback() {
                        @Override
                        public void onAdLoaded(@NonNull AdManagerInterstitialAd interstitialAd) {
                            
                            mAdManagerInterstitialAd = interstitialAd;
                            mAdManagerInterstitialAd.setFullScreenContentCallback(fullScreenContentCallback);
                            
                        }

                        @Override
                        public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                            // Handle the error                                
                            mAdManagerInterstitialAd = null;
                        }
                    

我还尝试使用 getApplicationContext() 而不是其他论坛建议的“this”来加载广告,但它没有用。

有什么想法吗?

android memory-leaks ads interstitial leakcanary
1个回答
0
投票

这更有可能是播放服务广告中的错误。

我的解决方法: 将 mAdManagerInterstitialAd 从活动移至单例。 然后使用回调和侦听器从引用存储在单例中的 mAdManagerInterstitialAd 的活动中调用“加载”和“显示”。

© www.soinside.com 2019 - 2024. All rights reserved.