The Problem: Implementation Crashes & Policy Violations
Integrating AdMob effectively requires careful threading and lifecycle management. A poorly implemented ad system can freeze the main thread, cause Application Not Responding (ANR) crashes, or violate Google's policies, resulting in a banned ad account.
Why It Happens
AdMob callbacks (like `OnAdLoaded` or `OnUserEarnedReward`) frequently fire on a background thread. If you attempt to update Unity UI or modify GameObjects directly inside these callbacks, Unity will throw an exception.
The Solution: Thread-Safe Rewarded Ads
Rewarded ads offer the highest eCPM and best user experience because they are opt-in. You must initialize the SDK, preload the ad, and safely dispatch the reward logic back to Unity's main thread.
Code Example: Loading & Showing Rewarded Ads
Here is a safe implementation pattern for loading and showing a Rewarded Ad:
using GoogleMobileAds.Api;
using UnityEngine;
using System.Collections.Generic;
using System;
public class AdManager : MonoBehaviour {
private RewardedAd rewardedAd;
private readonly string adUnitId = "ca-app-pub-3940256099942544/5224354917"; // Test ID
private Queue<Action> mainThreadActions = new Queue<Action>();
void Start() {
MobileAds.Initialize(initStatus => { LoadRewardedAd(); });
}
private void LoadRewardedAd() {
if (rewardedAd != null) { rewardedAd.Destroy(); }
RewardedAd.Load(adUnitId, new AdRequest(), (RewardedAd ad, LoadAdError error) => {
if (error == null) { rewardedAd = ad; }
});
}
public void ShowRewardedAd() {
if (rewardedAd != null && rewardedAd.CanShowAd()) {
rewardedAd.Show((Reward reward) => {
// Queue the UI/Game logic for the main thread
mainThreadActions.Enqueue(() => {
Debug.Log("Reward Granted on Main Thread!");
// Grant coins/lives here
});
});
}
}
void Update() {
while (mainThreadActions.Count > 0) {
mainThreadActions.Dequeue().Invoke();
}
}
}Common Mistakes
- Failing to clean up (destroy) old ad objects before loading new ones, leading to memory leaks.
- Manipulating Unity UI directly inside the reward callback without a thread-safe queue.
- Triggering interstitial ads unexpectedly, violating Google Play's intrusive ads policy.
Best Practices
Ensure your app registers your physical device ID in the MobileAds configuration to force test ads, even if you accidentally build with live IDs. Pair AdMob closely with Firebase Analytics to measure ARPDAU (Average Revenue Per Daily Active User).
Related Articles
If ad monetization isn't enough, consider implementing a hybrid model with Unity In-App Purchases. Also, watch out for Android build errors when combining Firebase and AdMob dependencies.
Conclusion
A successful AdMob integration respects the main thread, uses test ads during development, and provides clear opt-in value to the player. Proper lifecycle management ensures maximum revenue without sacrificing game stability.
