我也试过使用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
3条答案
按热度按时间sgtfey8w1#
根据InterstitialAd Docs:
单个InterstitialAd对象可用于在Activity的生命周期内请求和显示多个插播广告,因此您只需构造一次。
再次查看代码后,我注意到每次调用
refreshInterstitial()
方法时都要重新构造mInterstitialAd
。但是根据上面的文档,你应该在onCreate()
期间只构造一次mInterstitialAd
。在您的例子中,**内存泄漏的主要原因是:**您仍然有一个活动的侦听器(绑定到Activity寿命),但您使用另一个侦听器重新构建了一个新的
InterstitialAd
示例。因此,解决方案是重用
InterstitialAd
示例及其侦听器,而无需重新分配。我建议将refreshInterstitial()
方法简化为:然后将
mInterstitialAd
赋值给onCreate()
。此解决方案与您可以在此处找到的解决方案类似。kzmpq1sx2#
这是为我工作:(在ActivityMain()中):
在片段中:
LeakCanary显示:
==================================堆分析结果=====================================================================================================================================================================================================================
z9smfwbn3#
我在插播广告中也遇到了同样的问题,通过将FullScreenContentCallback在其所有重写方法中设置为null来解决。