Реалізація міжсторінкової реклами (Interstitial) у мобільному додатку
Interstitial — повноекранний формат, який показується в точках природних пауз: між рівнями в грі, після завершення дії, при переході між розділами. Дохід з одного показу в 5–15 разів вищий за банер, але ціна помилки вища: неміцна interstitial — це видалення додатку.
Управління життєвим циклом: де ломається найчастіше
Головна помилка — показувати interstitial одразу після завантаження, а не откладувати до потрібного моменту. Користувач відкрив додаток, не встиг зрозуміти що здесь відбувається — уже повний екран реклами. Google це виловлює та понижує додаток у пошуку.
На Android типова проблема — утечка Activity. Паттерн «завантажити в singleton, показати з будь-якої Activity» виглядає зручно, але InterstitialAd тримає reference на Context. Якщо Activity знищена, а об'єкт живий — отримуємо leak + WindowManager$BadTokenException при спробі показати на неіснуючому вікні.
Правильний підхід: завантажуємо у ViewModel або presenter з applicationContext, показуємо через активну Activity, яку передаємо через WeakReference або через лямбду в момент показу:
class InterstitialManager(private val appContext: Context) {
private var interstitialAd: InterstitialAd? = null
fun load() {
InterstitialAd.load(appContext, AD_UNIT_ID, AdRequest.Builder().build(),
object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) { interstitialAd = ad }
override fun onAdFailedToLoad(error: LoadAdError) { interstitialAd = null }
})
}
fun show(activity: Activity) {
interstitialAd?.show(activity) ?: load() // показали — одразу починаємо завантажувати наступний
}
}
Після show() об'єкт стає недійсним — потрібен новий InterstitialAd.load(). Забутий load() після показу — часта причина «реклама показалася один раз та все».
Стратегія показу
Ефективний interstitial потребує продуманої стратегії, а не «показувати як можна частіше»:
Cooldown між показами. Мінімум 30–60 секунд між interstitials. Реалізується через timestamp останнього показу у SharedPreferences/UserDefaults. Google рекомендує не частіше раза на 3–5 хвилин для більшості категорій.
Точки показу. Гарні точки: завершення рівня, збереження результату, перехід у головне меню. Погані: при натисненні Back, при відкритті повідомлення, при першому запуску.
Попередня завантаження. Interstitial потрібно завантажувати заблаговременно — запит до сервера займає 1–3 секунди. Якщо завантажувати в момент показу — пауза буде помітна. Правильно: завантажити одразу після попереднього показу або при початку рівня.
iOS-специфіка
На iOS GADInterstitialAd — не багаторазовий об'єкт. Один інстанс — один показ. Спроба викликати present(fromRootViewController:) повторно дає помилку в логах та нічого не показує. Створюємо новий інстанс після кожного показу через GADInterstitialAd.load(withAdUnitID:request:completionHandler:).
Важливий rootViewController — передавайте актуальний VC, а не window?.rootViewController. Якщо сверху є модальний контроллер, interstitial потрібно показувати поверх нього: presentedViewController ?? rootViewController.
Обробка подій
Мінімальний набір для аналітики:
-
onAdImpression/adDidRecordImpression— засчитуємо показ -
onAdDismissedFullScreenContent/adDidDismissFullScreenContent— продовжуємо користувальницький сценарій -
onAdFailedToShowFullScreenContent— логуємо помилку, не блокуємо UX
Графіки реалізації — 1–2 дні з урахуванням стратегії показу та тестування на кількох пристроях.







