我正在使用AdView和LeakCanary。托管adView的Fragment在onDestroy中调用adView.destroy(),但LeakCanary显示托管此Fragment的Activity泄漏了com.google.android.gms.common.api.a.a.a.i。堆转储还显示有内存泄漏。当我删除AdView.loadAd()并且不在Fragment中加载广告时-就没有泄漏了。有什么想法或建议吗?谢谢。
我正在使用AdView和LeakCanary。托管adView的Fragment在onDestroy中调用adView.destroy(),但LeakCanary显示托管此Fragment的Activity泄漏了com.google.android.gms.common.api.a.a.a.i。堆转储还显示有内存泄漏。当我删除AdView.loadAd()并且不在Fragment中加载广告时-就没有泄漏了。有什么想法或建议吗?谢谢。
同样的问题,AdView有一个内部变量(强引用)持有上下文,也就是我的Activity,导致Activity实例泄漏。
我的依赖项是com.google.android.gms:play-services-ads:8.3.0
一个解决方法是在创建AdView实例时提供应用程序上下文。
AdView adview = new AdView(getApplicationContext());
我认为将应用上下文传递给AdView并不是真正的解决方案。因为问题在于AdView没有释放Context对象。因此,如果您传递它,它将不会释放App上下文。
因此,以下可作为防止泄漏的解决方法。
@Override
protected void onDestroyView() {
super.onDestroy();
if (adview != null && adview.getParent() != null) // inflated by XML and remove here from parent
((ViewGroup) adview.getParent()).removeView(adview);
adview.destroy();
adview = null;
}
onDestroyView
中销毁AdviewonDestroyView
方法,在视图被销毁时调用,因此您应该确切地在这个位置销毁AdView。onDestroy
(在onDestroyView之后)销毁AdView,所以这是一个泄漏。因为AdView仍然存在于Fragment View被销毁之后。onDestroyView
方法,在Activity中,视图在onDestroy
中被销毁。所以我们在onDestroy
中清除对象。但如果我们在XML中使用adView,则无法完成此操作。
因为您希望从XML中填充AdView,所以在onDestroy
中删除View将为您完成工作。
onDestroyView
中使AdView为NULL在onDestroy
中将AdView设置为null
。因此,AdView对象将不再被引用,并且将由垃圾收集器清理。
我希望这些信息对您有用。 :)
com.google.android.gms.internal.ads.zzml
持有。Google真丢人,从第一个广告SDK版本发布到现在已经9年了,但他们仍未解决此问题。 - Son Truong您可以尝试以下操作:
first remove your adView
from its container and then call destroy(), i.e.
ViewParent parent = adView.getParent();
if (parent != null && parent instanceof ViewGroup) {
((ViewGroup) parent).removeView(adView);
}
adView.destroy();
adView = null;
com.google.android.gms.ads.doubleclick.PublisherAdView
;2)我没有在广告中使用片段,而是直接添加和处理活动视图树。 - Dimitar Genovthis
。将 this
更改为 applicationContext
后,问题得到解决。
更改前:
MobileAds.initialize(this, "ca-app-pub-0000000000000000~0000000000")
之后:
MobileAds.initialize(applicationContext, "ca-app-pub-0000000000000000~0000000000")
我尝试了stackoverflow论坛和所有其他Google论坛中讨论的所有解决方案。内存泄漏似乎是不稳定的:如果用户在显示广告之前离开活动,则出现内存泄漏的机会更高。
唯一有效的方法是将内存泄漏限制在一个单独的活动中...
第一个建议: 不要直接将adview添加到XML布局文件中。 如果按照官方文档(https://developers.google.com/admob/android/banner)中的说明操作,那么一定会导致内存泄漏。 相反,请以编程方式添加adview:
从XML文件中删除adview:注意:这是一个解决方法,而不是解决方案。解决方案应该只来自谷歌:像“mAdView.destroy()”这样的简单命令就可以解决问题,对吧?
此问题正在Google论坛上讨论:https://groups.google.com/forum/#!topic/google-admob-ads-sdk/9IyjqdmeumM