Использование памяти Android AdMob
Я смущен тем, насколько важна память AdMob SDK, и где эта память находится на самом деле. Позвольте мне объяснить.
У меня есть два варианта моего приложения: Free and Paid. В бесплатной версии есть объявления AdMob, в противном случае код почти одинаковый (используется обычная версия Android).
Я запускаю приложения на своем Nexus 4 (Android 4.2.1) и сравниваю использование памяти.
Я смотрю на системную память, используемую приложением в настройках устройствa > apps > running.
Я также смотрю на память кучи Dalvik, как сообщается сообщениями GC logcat, и используя файлы HPROF.
Когда я запускаю Платную версию, я вижу:
- Системная память: около 16 МБ
- Размер кучи Dalvik: около 10 МБ
Когда я запускаю бесплатную версию, я вижу:
- Системная память: около 29 МБ
- Размер кучи Dalvik: около 11 МБ
Другими словами, размер кучи dalvik аналогичен для обеих версий.
Но фактическая системная память - 10 МБ + выше!
Проведя время, изучая профилирование памяти (http://www.youtube.com/watch?feature=player_embedded&v=_CruQY55HOk) и часы, смотрящие на файлы HPROF, чтобы удалить любую возможную утечку, я могу видеть только один вывод:
Дополнительная системная память на 10 Мбайт, используемая AdMob, на самом деле является собственной памятью, выделенной с помощью malloc, за пределами dalvik heap!
Теперь мне интересно о двух вещах:
- Я считаю, что, поскольку свободная версия системная память на 10 Мбайт больше
чем платная версия, гораздо более склонна быть убитой ОС в случае
давления памяти. Или же ОС Android учитывает только
куча Dalvik для решения, какое приложение убить?
- Есть ли способ настроить SDK AdMob, чтобы выбрать, сколько памяти оно
разрешено выделять?
Большое спасибо
Ответы
Ответ 1
AdMob использует WebView для загрузки объявлений. Это довольно сложный объект, который использует собственные библиотеки и подвержен сбоям. SDK AdMob пытается сделать его управляемым, но на самом деле у вас нет никакого контроля над тем, как он работает. Кроме того, использование памяти, вероятно, будет варьироваться в зависимости от типа объявления: текстовые тексты HTML и баннеры с изображениями и т.д.
Итак, если вы не хотите бинарно-запланировать AdMob (это не открытый исходный код), вам просто нужно жить с ним. Вы можете удалить и уничтожить AdView
проактивно, чтобы уменьшить любые утечки, но не намного больше вы можете сделать.
Ответ 2
Испытав мое приложение с двумя различными реализациями AdMob, я обнаружил, что его реализация через java-код, а не XML, легче подходит для приложения.
Обновление №1:
Вы также можете добавить пользовательских слушателей для уничтожения через некоторое время и воссоздать, чтобы справиться с этим еще лучше. В Serverside также есть параметр, показывающий объявление приложения, как скоро следует запросить новое объявление, я не уверен, что он существует во всех случаях, но он существует для учетных записей DFP.
Хорошим предлагаемым способом реализации объявления является то, что:
new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (!isBeingDestroyed) {
final AdRequest adRequest = new AdRequest();
final AdView adView = (AdView) findViewById(R.id.ad);
adView.loadAd(adRequest);
}
}).sendEmptyMessageDelayed(0, 1000);
также не забывайте вызывать операцию adView.destroy()
onDestroy() или когда вы этого больше не хотите!
Вышеупомянутый способ упоминается здесь со многими полезными выпусками памяти!
Обновление №2: (улучшение при обновлении №1)
Улучшение предложенного метода обработчика.
Используя этот способ, вы избегаете (я надеюсь) обратных вызовов обработчика, которые могут быть уложены в стек, когда намеренно создается или уничтожается действие до отправки сообщения с задержкой. Это более вероятно, если вы решите увеличить 1000
миллисекунды:
Создать поле для обработчика:
private adHandler;
На вашем onCreate
:
adHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (!isBeingDestroyed) {
final AdRequest adRequest = new AdRequest();
final AdView adView = (AdView) findViewById(R.id.ad);
adView.loadAd(adRequest);
}
return false;
}
});
adHandler.sendEmptyMessageDelayed(0, 1000);
На вашем onDestroy
не забудьте "освободить" обработчик:
adHandler.removeCallbacksAndMessages(null);
null удаляет любые обратные вызовы, см. doc