Interstitial Ad Implementation in Mobile Application
Interstitial is fullscreen format shown in natural pause points: between game levels, after task completion, when transitioning between sections. Revenue from one impression is 5–15 times higher than banner, but cost of error is higher: inappropriate interstitial — app deletion.
Lifecycle Management: Where It Breaks Most Often
Main error — show interstitial immediately after load, not defer to right moment. User opened app, didn't understand what's happening — already fullscreen ad. Google catches this and downgrades app in search.
On Android typical problem — Activity leak. Pattern "load in singleton, show from any Activity" looks convenient, but InterstitialAd holds reference to Context. If Activity destroyed but object alive — get leak + WindowManager$BadTokenException when trying to show on non-existent window.
Correct approach: load in ViewModel or presenter with applicationContext, show via active Activity passed through WeakReference or lambda at show moment:
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() // showed — immediately start loading next
}
}
After show() object becomes invalid — need new InterstitialAd.load(). Forgotten load() after show — common reason "ad showed once and that's it."
Display Strategy
Effective interstitial requires planned strategy, not "show as often as possible":
Cooldown between shows. Minimum 30–60 seconds between interstitials. Implemented via last show timestamp in SharedPreferences/UserDefaults. Google recommends no more than once per 3–5 minutes for most categories.
Show points. Good points: level completion, result save, main menu transition. Bad: on back tap, on notification open, on first launch.
Preloading. Interstitial must load in advance — server request takes 1–3 seconds. If loading at show time — pause will be noticeable. Correct: load right after previous show or at level start.
iOS Specifics
On iOS GADInterstitialAd — not reusable object. One instance — one show. Attempting present(fromRootViewController:) again gives error in logs and shows nothing. Create new instance after each show via GADInterstitialAd.load(withAdUnitID:request:completionHandler:).
Important rootViewController — pass current VC, not window?.rootViewController. If modal controller on top, interstitial must show over it: presentedViewController ?? rootViewController.
Event Handling
Minimal set for analytics:
-
onAdImpression/adDidRecordImpression— count show -
onAdDismissedFullScreenContent/adDidDismissFullScreenContent— continue user scenario -
onAdFailedToShowFullScreenContent— log error, don't block UX
Timelines for implementation — 1–2 days including display strategy and testing on multiple devices.







