Я использую AdView и LeakCanary. Фрагмент, в котором размещается adView, вызывает adView.destroy() в onDestroy, но LeakCanary показывает, что Activity, в котором размещен этот фрагмент, просачивается com.google.android.gms.common.api.a.a.a.i , Сброс кучи также показывает, что есть утечка памяти. Когда я удаляю AdView.loadAd() и не загружаю Ad в фрагмент - утечки нет. Любые мысли или предложения? Благодарю.
AdView вызывает утечку памяти
Ответ 1
Такая же проблема, у AdView есть внутренняя переменная (сильная ссылка), удерживающая контекст, который является моей Activity, вызывая утечку экземпляра Activity.
Моя зависимость com.google.android.gms:play-services-ads:8.3.0
A обходной путь заключается в предоставлении контекста приложения при создании экземпляра AdView.
AdView adview = new AdView(getApplicationContext());
Ответ 2
Можете ли вы попробовать следующее:
- переместите свою логику в onDestroyView()
-
сначала удалите ваш
adView
из своего контейнера, а затем вызовите destroy(), т.е.ViewParent parent = adView.getParent(); if (parent != null && parent instanceof ViewGroup) { ((ViewGroup) parent).removeView(adView); } adView.destroy(); adView = null;
Ответ 3
Я думаю, что передача контекста приложения в AdView не является решением на самом деле. Потому что проблема в том, что AdView не освобождает объект Context. Так что это не освободит контекст приложения, если вы передадите его.
Так что ниже может быть обходной путь, чтобы действительно предотвратить утечку.
@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;
}
1. Уничтожить рекламу в onDestroyView
- У жизненного цикла фрагмента есть метод
onDestroyView
, который вызывается при уничтожении представления, поэтому в этом месте вы должны точно уничтожить AdView. - В вашем случае вы уничтожаете AdView в
onDestroy
(после onDestroyView), так что это утечка. Потому что AdView все еще там после того, как Fragment View уничтожен. - Деятельность не имеет метода
onDestroyView
, представление уничтожается вonDestroy
в деятельности. Так что мыonDestroy
объекты вonDestroy
.
2. Удалите AdView из View программным способом.
Но если мы используем adView в XML, то это невозможно.
Поскольку вы хотите раздувать AdView из XML, удаление "View in onDestroy
сделает эту работу за вас.
3. Сделайте AdView пустым в onDestroyView
Сделайте AdView null
в onDestroy
. Таким образом, объект AdView больше не будет ссылаться. и он будет очищен сборщиком мусора.
Я надеюсь, что эта информация полезна для вас. :)
Ответ 4
В моем случае, это было вызвано использованием MobileAds коды инициализации с this
в рамках лямбды. После изменения this
к applicationContext
, она была установлена.
До:
MobileAds.initialize(this, "ca-app-pub-0000000000000000~0000000000")
После:
MobileAds.initialize(applicationContext, "ca-app-pub-0000000000000000~0000000000")