Подтвердить что ты не робот

Использование памяти 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, чтобы выбрать, сколько памяти оно разрешено выделять?

Большое спасибо

4b9b3361

Ответ 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