AppLovin Ads: The Ultimate Developer’s Cheatsheet

Introduction to AppLovin

AppLovin is a leading mobile marketing platform that provides developers with tools for user acquisition, monetization, and analytics. Founded in 2012, it offers various ad formats and mediation solutions that help mobile app developers grow their businesses through effective advertising strategies.

Key benefits of AppLovin include:

  • Comprehensive monetization solutions across multiple ad formats
  • Advanced machine learning algorithms for optimization
  • Simplified SDK integration process
  • Robust reporting and analytics tools
  • Access to high-quality demand sources through the AppLovin Exchange
  • MAX mediation platform to maximize ad revenue

Core AppLovin Products

ProductDescriptionBest Used For
AppLovin SDKCore software development kit that enables ad display in mobile appsBasic integration of AppLovin ads into mobile applications
MAXAdvanced in-app mediation platform that optimizes revenue across multiple ad networksMaximizing revenue by managing multiple ad networks with a single SDK
AppDiscoveryUser acquisition platform for driving app installsAcquiring new users for your app
SparkLabsIn-house creative team that designs ad creativesCreating high-performing ad creatives
AppLovin ExchangeMarketplace connecting advertisers with publishersAccessing premium demand
AXONMachine learning engine that powers optimizationAutomated optimization of ad performance

SDK Integration

SDK Version & Requirements

PlatformLatest SDK VersionMinimum OS RequirementsDownload Size
iOS11.11.3+iOS 9.0+~500KB (base), ~3-6MB (with dependencies)
Android11.11.3+Android 4.4+ (API level 19+)~400KB (base), ~3-5MB (with dependencies)
Unity11.11.3+Unity 2017.4+Depends on platform
Flutter2.0.0+Flutter 1.20.0+Depends on platform
React Native11.11.3+React Native 0.60.0+Depends on platform

Basic Integration Steps – iOS

// 1. Add AppLovin SDK to your project using CocoaPods
// In your Podfile:
pod 'AppLovinSDK'

// 2. Initialize the SDK in your AppDelegate
import AppLovinSDK

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    ALSdk.shared()!.mediationProvider = "max"
    ALSdk.shared()!.initializeSdk { (configuration: ALSdkConfiguration) in
        // SDK has been initialized, start loading ads
    }
    return true
}

// 3. Set up privacy settings (before initialization)
let privacySettings = ALPrivacySettings()
privacySettings.hasUserConsent = true  // Set based on user consent
privacySettings.isAgeRestrictedUser = false  // Set based on user age
privacySettings.isDoNotSell = false  // Set for CCPA compliance

Basic Integration Steps – Android

// 1. Add AppLovin SDK to your project
// In your build.gradle (app level):
dependencies {
    implementation 'com.applovin:applovin-sdk:11.11.3'
}

// 2. Initialize the SDK in your Application class
import com.applovin.sdk.AppLovinSdk;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        AppLovinSdk.getInstance(this).setMediationProvider("max");
        AppLovinSdk.initializeSdk(this, new AppLovinSdk.SdkInitializationListener() {
            @Override
            public void onSdkInitialized(AppLovinSdkConfiguration config) {
                // SDK has been initialized, start loading ads
            }
        });
    }
}

// 3. Add your SDK key to AndroidManifest.xml
// Inside the <application> tag:
<meta-data android:name="applovin.sdk.key"
           android:value="YOUR_SDK_KEY" />

// 4. Set up privacy settings (before initialization)
AppLovinPrivacySettings.setHasUserConsent(true, context); // Set based on user consent
AppLovinPrivacySettings.setIsAgeRestrictedUser(false, context); // Set based on user age
AppLovinPrivacySettings.setDoNotSell(false, context); // Set for CCPA compliance

Basic Integration Steps – Unity

// 1. Import the AppLovin MAX SDK Unity package

// 2. Initialize the SDK in a MonoBehaviour script
using AppLovinMax;

private const string MaxSdkKey = "YOUR_APPLOVIN_SDK_KEY";

void Start()
{
    MaxSdkCallbacks.OnSdkInitializedEvent += (MaxSdkBase.SdkConfiguration sdkConfiguration) => {
        // SDK has been initialized, start loading ads
    };
    
    // Set privacy settings
    MaxSdk.SetHasUserConsent(true); // Set based on user consent
    MaxSdk.SetIsAgeRestrictedUser(false); // Set based on user age
    MaxSdk.SetDoNotSell(false); // Set for CCPA compliance
    
    // Initialize the SDK
    MaxSdk.SetSdkKey(MaxSdkKey);
    MaxSdk.InitializeSdk();
}

Ad Format Implementation

Banner Ads

PropertyDetails
Ad SizesStandard: 320×50, Leader: 728×90, MREC: 300×250
PlacementsTop or bottom of screen, or custom position
Refresh RateDefault: 60 seconds (configurable)
Load TimeTypically 1-2 seconds

iOS Banner Implementation

import AppLovinSDK

class ViewController: UIViewController, MAAdViewAdDelegate {
    var adView: MAAdView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Create banner ad
        adView = MAAdView(adUnitIdentifier: "YOUR_AD_UNIT_ID")
        adView.delegate = self
        
        // Set up ad parameters
        adView.frame = CGRect(x: 0, y: view.frame.size.height - 50, width: view.frame.size.width, height: 50)
        
        // Load the ad
        view.addSubview(adView)
        adView.loadAd()
    }
    
    // MARK: - MAAdViewAdDelegate
    
    func didLoad(_ ad: MAAd) {
        // Banner ad loaded
    }
    
    func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
        // Banner ad failed to load
    }
    
    func didClick(_ ad: MAAd) {
        // Banner ad clicked
    }
}

Android Banner Implementation

import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxAdViewAdListener;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.ads.MaxAdView;

public class MainActivity extends AppCompatActivity implements MaxAdViewAdListener {
    private MaxAdView adView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // Create banner ad
        adView = new MaxAdView("YOUR_AD_UNIT_ID", this);
        adView.setListener(this);
        
        // Set up ad parameters
        int width = ViewGroup.LayoutParams.MATCH_PARENT;
        int heightDp = MaxAdFormat.BANNER.getAdaptiveSize(this).getHeight();
        int heightPx = AppLovinSdkUtils.dpToPx(this, heightDp);
        
        adView.setLayoutParams(new FrameLayout.LayoutParams(width, heightPx));
        
        // Add to view hierarchy and load
        ViewGroup rootView = findViewById(R.id.main_container);
        rootView.addView(adView);
        adView.loadAd();
    }
    
    // MaxAdViewAdListener implementation
    @Override
    public void onAdLoaded(MaxAd ad) {
        // Banner ad loaded
    }
    
    @Override
    public void onAdLoadFailed(String adUnitId, MaxError error) {
        // Banner ad failed to load
    }
    
    @Override
    public void onAdClicked(MaxAd ad) {
        // Banner ad clicked
    }
    
    // Other required listener methods...
}

Interstitial Ads

PropertyDetails
FormatFull-screen ads shown at natural transition points
Frequency CapRecommended: Every 3-4 minutes (configurable)
Best PracticesShow between levels, after completing tasks
Load TimeTypically 1-3 seconds (preload recommended)

iOS Interstitial Implementation

import AppLovinSDK

class ViewController: UIViewController, MAAdDelegate {
    var interstitialAd: MAInterstitialAd!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Create interstitial ad
        interstitialAd = MAInterstitialAd(adUnitIdentifier: "YOUR_AD_UNIT_ID")
        interstitialAd.delegate = self
        
        // Load the ad
        interstitialAd.load()
    }
    
    func showInterstitialIfReady() {
        if interstitialAd.isReady {
            interstitialAd.show()
        }
    }
    
    // MARK: - MAAdDelegate
    
    func didLoad(_ ad: MAAd) {
        // Interstitial ad loaded
    }
    
    func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
        // Interstitial ad failed to load
        // Retry with exponential backoff
        retryAttempt += 1
        let delaySec = pow(2.0, min(6.0, retryAttempt))
        
        DispatchQueue.main.asyncAfter(deadline: .now() + delaySec) {
            self.interstitialAd.load()
        }
    }
    
    func didDisplay(_ ad: MAAd) {
        // Interstitial ad displayed
        retryAttempt = 0
    }
    
    func didHide(_ ad: MAAd) {
        // Interstitial ad hidden
        interstitialAd.load() // Load the next ad
    }
    
    func didClick(_ ad: MAAd) {
        // Interstitial ad clicked
    }
    
    // Other delegate methods...
    
    private var retryAttempt = 0
}

Android Interstitial Implementation

import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxAdListener;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.ads.MaxInterstitialAd;

public class MainActivity extends AppCompatActivity implements MaxAdListener {
    private MaxInterstitialAd interstitialAd;
    private int retryAttempt = 0;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // Create interstitial ad
        interstitialAd = new MaxInterstitialAd("YOUR_AD_UNIT_ID", this);
        interstitialAd.setListener(this);
        
        // Load the ad
        interstitialAd.loadAd();
    }
    
    public void showInterstitialIfReady() {
        if (interstitialAd.isReady()) {
            interstitialAd.showAd();
        }
    }
    
    // MaxAdListener implementation
    @Override
    public void onAdLoaded(MaxAd ad) {
        // Interstitial ad loaded
        retryAttempt = 0;
    }
    
    @Override
    public void onAdLoadFailed(String adUnitId, MaxError error) {
        // Interstitial ad failed to load
        // Retry with exponential backoff
        retryAttempt++;
        long delayMillis = (long) Math.pow(2, Math.min(6, retryAttempt)) * 1000;
        
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                interstitialAd.loadAd();
            }
        }, delayMillis);
    }
    
    @Override
    public void onAdDisplayed(MaxAd ad) {
        // Interstitial ad displayed
    }
    
    @Override
    public void onAdHidden(MaxAd ad) {
        // Interstitial ad hidden
        interstitialAd.loadAd(); // Load the next ad
    }
    
    @Override
    public void onAdClicked(MaxAd ad) {
        // Interstitial ad clicked
    }
    
    // Other required listener methods...
}

Rewarded Ads

PropertyDetails
FormatFull-screen ads that reward users for watching
Reward TypesVirtual currency, extra lives, power-ups, content unlock
Completion RateTypically 70-85% (users choose to watch)
Best PracticesImplement as user choice, clearly communicate reward

iOS Rewarded Implementation

import AppLovinSDK

class ViewController: UIViewController, MARewardedAdDelegate {
    var rewardedAd: MARewardedAd!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Create rewarded ad
        rewardedAd = MARewardedAd.shared(withAdUnitIdentifier: "YOUR_AD_UNIT_ID")
        rewardedAd.delegate = self
        
        // Load the ad
        rewardedAd.load()
    }
    
    func showRewardedIfReady() {
        if rewardedAd.isReady {
            rewardedAd.show()
        }
    }
    
    // MARK: - MARewardedAdDelegate
    
    func didLoad(_ ad: MAAd) {
        // Rewarded ad loaded
    }
    
    func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
        // Rewarded ad failed to load
        // Retry with exponential backoff similar to interstitial
    }
    
    func didStartRewardedVideo(for ad: MAAd) {
        // Rewarded ad started playing
    }
    
    func didCompleteRewardedVideo(for ad: MAAd) {
        // Rewarded ad completed playing
    }
    
    func didRewardUser(for ad: MAAd, with reward: MAReward) {
        // User earned reward
        let rewardAmount = reward.amount
        let rewardType = reward.label
        
        // Provide reward to user
    }
    
    func didHide(_ ad: MAAd) {
        // Rewarded ad hidden
        rewardedAd.load() // Load the next ad
    }
    
    // Other delegate methods...
}

Android Rewarded Implementation

import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.MaxReward;
import com.applovin.mediation.MaxRewardedAdListener;
import com.applovin.mediation.ads.MaxRewardedAd;

public class MainActivity extends AppCompatActivity implements MaxRewardedAdListener {
    private MaxRewardedAd rewardedAd;
    private int retryAttempt = 0;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // Create rewarded ad
        rewardedAd = MaxRewardedAd.getInstance("YOUR_AD_UNIT_ID", this);
        rewardedAd.setListener(this);
        
        // Load the ad
        rewardedAd.loadAd();
    }
    
    public void showRewardedIfReady() {
        if (rewardedAd.isReady()) {
            rewardedAd.showAd();
        }
    }
    
    // MaxRewardedAdListener implementation
    @Override
    public void onRewardedVideoStarted(MaxAd ad) {
        // Rewarded ad started playing
    }
    
    @Override
    public void onRewardedVideoCompleted(MaxAd ad) {
        // Rewarded ad completed playing
    }
    
    @Override
    public void onUserRewarded(MaxAd ad, MaxReward reward) {
        // User earned reward
        int rewardAmount = reward.getAmount();
        String rewardType = reward.getLabel();
        
        // Provide reward to user
    }
    
    @Override
    public void onAdLoaded(MaxAd ad) {
        // Rewarded ad loaded
        retryAttempt = 0;
    }
    
    @Override
    public void onAdLoadFailed(String adUnitId, MaxError error) {
        // Rewarded ad failed to load
        // Retry with exponential backoff
    }
    
    @Override
    public void onAdHidden(MaxAd ad) {
        // Rewarded ad hidden
        rewardedAd.loadAd(); // Load the next ad
    }
    
    // Other required listener methods...
}

App Open Ads

PropertyDetails
FormatFull-screen ads shown during app launch or resume
Best PlacementApp launch, app resume after background
Frequency CapRecommended: Once per 4+ hours
Important NoteRespect user experience; avoid disrupting critical flows

iOS App Open Implementation

import AppLovinSDK

class AppOpenManager: NSObject, MAAdDelegate {
    static let shared = AppOpenManager()
    
    private var appOpenAd: MAAppOpenAd?
    private var loadTime: Date?
    
    private override init() {
        super.init()
        appOpenAd = MAAppOpenAd(adUnitIdentifier: "YOUR_AD_UNIT_ID")
        appOpenAd?.delegate = self
    }
    
    func loadAd() {
        appOpenAd?.load()
    }
    
    func showAdIfReady() {
        // Check if ad exists and is not expired (loaded more than 4 hours ago)
        if appOpenAd?.isReady == true && isAdNotExpired() {
            appOpenAd?.show()
        } else {
            loadAd()
        }
    }
    
    private func isAdNotExpired() -> Bool {
        guard let loadTime = loadTime else { return false }
        let now = Date()
        let timeIntervalSinceLoad = now.timeIntervalSince(loadTime)
        return timeIntervalSinceLoad <= 4 * 3600 // 4 hours
    }
    
    // MARK: - MAAdDelegate
    
    func didLoad(_ ad: MAAd) {
        loadTime = Date()
    }
    
    func didFailToLoadAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
        // Handle load failure
    }
    
    func didDisplay(_ ad: MAAd) {
        // App open ad displayed
    }
    
    func didHide(_ ad: MAAd) {
        // App open ad hidden
        loadAd() // Load next ad
    }
    
    // Other delegate methods...
}

// In AppDelegate:
func applicationDidBecomeActive(_ application: UIApplication) {
    AppOpenManager.shared.showAdIfReady()
}

Android App Open Implementation

import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxAdListener;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.ads.MaxAppOpenAd;

public class AppOpenManager implements MaxAdListener, LifecycleObserver {
    private static AppOpenManager instance;
    private MaxAppOpenAd appOpenAd;
    private long loadTime = 0;
    private Activity currentActivity;
    
    public static AppOpenManager getInstance() {
        if (instance == null) {
            instance = new AppOpenManager();
        }
        return instance;
    }
    
    public void init(Application application) {
        appOpenAd = new MaxAppOpenAd("YOUR_AD_UNIT_ID", application);
        appOpenAd.setListener(this);
        
        // Register lifecycle callbacks
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    public void onStart() {
        showAdIfReady();
    }
    
    public void loadAd() {
        appOpenAd.loadAd();
    }
    
    public void showAdIfReady() {
        // Check if ad exists and is not expired (loaded more than 4 hours ago)
        if (appOpenAd.isReady() && !isAdExpired()) {
            appOpenAd.showAd();
        } else {
            loadAd();
        }
    }
    
    private boolean isAdExpired() {
        long now = System.currentTimeMillis();
        long hoursElapsed = (now - loadTime) / (60 * 60 * 1000);
        return hoursElapsed > 4; // 4 hours
    }
    
    @Override
    public void onAdLoaded(MaxAd ad) {
        loadTime = System.currentTimeMillis();
    }
    
    @Override
    public void onAdHidden(MaxAd ad) {
        loadAd(); // Load next ad
    }
    
    // Other required listener methods...
}

Native Ads

PropertyDetails
FormatCustomizable ads that match app UI/UX
ComponentsIcon, headline, description, CTA button, media view
TemplatesGrid, list, carousel, custom layouts
Best PracticesMatch app’s design language, label as “Ad” or “Sponsored”

iOS Native Ad Implementation

import AppLovinSDK

class NativeAdViewController: UIViewController, MANativeAdDelegate, MAAdViewAdDelegate {
    var nativeAdLoader: MANativeAdLoader!
    var nativeAd: MAAd?
    
    @IBOutlet weak var nativeAdView: MANativeAdView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Create native ad loader
        nativeAdLoader = MANativeAdLoader(adUnitIdentifier: "YOUR_AD_UNIT_ID")
        nativeAdLoader.nativeAdDelegate = self
        nativeAdLoader.adViewAdDelegate = self
        
        // Load native ad
        nativeAdLoader.loadAd(into: nativeAdView)
    }
    
    // MARK: - MANativeAdDelegate
    
    func didLoadNativeAd(_ nativeAdView: MANativeAdView?, for ad: MAAd) {
        // Native ad loaded
        nativeAd = ad
        
        // Add nativeAdView to your view hierarchy if using manual integration
        if let adView = nativeAdView {
            // Add adView to container
        }
    }
    
    func didFailToLoadNativeAd(forAdUnitIdentifier adUnitIdentifier: String, withError error: MAError) {
        // Native ad failed to load
    }
    
    // MARK: - MAAdViewAdDelegate
    
    func didClick(_ ad: MAAd) {
        // Native ad clicked
    }
}

Android Native Ad Implementation

import com.applovin.mediation.MaxAd;
import com.applovin.mediation.MaxError;
import com.applovin.mediation.nativeAds.MaxNativeAdListener;
import com.applovin.mediation.nativeAds.MaxNativeAdLoader;
import com.applovin.mediation.nativeAds.MaxNativeAdView;

public class NativeAdActivity extends AppCompatActivity {
    private MaxNativeAdLoader nativeAdLoader;
    private MaxAd nativeAd;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_native_ad);
        
        // Create native ad loader
        nativeAdLoader = new MaxNativeAdLoader("YOUR_AD_UNIT_ID", this);
        nativeAdLoader.setNativeAdListener(new MaxNativeAdListener() {
            @Override
            public void onNativeAdLoaded(final MaxNativeAdView nativeAdView, final MaxAd ad) {
                // Native ad loaded
                // Clean up previous ad
                if (nativeAd != null) {
                    nativeAdLoader.destroy(nativeAd);
                }
                
                nativeAd = ad;
                
                // Add nativeAdView to your view hierarchy
                FrameLayout adContainer = findViewById(R.id.native_ad_container);
                adContainer.removeAllViews();
                adContainer.addView(nativeAdView);
            }
            
            @Override
            public void onNativeAdLoadFailed(final String adUnitId, final MaxError error) {
                // Native ad failed to load
            }
            
            @Override
            public void onNativeAdClicked(final MaxAd ad) {
                // Native ad clicked
            }
        });
        
        // Load native ad
        nativeAdLoader.loadAd();
    }
    
    @Override
    protected void onDestroy() {
        if (nativeAd != null) {
            nativeAdLoader.destroy(nativeAd);
        }
        
        super.onDestroy();
    }
}

MAX Mediation

Mediation Setup

  1. Create a MAX account at AppLovin.com
  2. Create an app in the MAX dashboard
  3. Set up ad networks:
    • Select desired ad networks
    • Follow network-specific setup instructions
    • Enter credentials for each network
  4. Create ad units for each format
  5. Set up waterfall (automatic or manual priority)
  6. Configure bidding for supported networks

Supported Ad Networks

NetworkBannerInterstitialRewardedNativeApp Open
AdColony✓✓✓✓✗
AdMob✓✓✓✓✓
AppLovin Exchange✓✓✓✓✓
Chartboost✓✓✓✓✗
Facebook (Meta Audience Network)✓✓✓✓✗
ironSource✓✓✓✓✗
Mintegral✓✓✓✓✗
Tapjoy✗✓✓✗✗
Unity Ads✓✓✓✗✗
Vungle✓✓✓✓✗
Yahoo✓✓✓✓✗

Bidding vs Waterfall

FeatureBiddingWaterfall
How It WorksReal-time auction among all networksSequential calls to networks in order of priority
AdvantagesHigher revenue, faster load times, less latencyMore control over ad sources
DisadvantagesLimited network supportPotential revenue loss, higher latency
Setup ComplexitySimple (automatic optimization)Complex (manual optimization)
Best ForMost apps, especially high-volume appsSpecial cases requiring manual control

Network-Specific Setup Tips

NetworkRequired IDsSpecial Considerations
AdMobApp ID, Ad Unit IDsRequires Google Play Services, separate iOS/Android setup
FacebookApp ID, Placement IDsRequires Facebook App ID even for ads only
Unity AdsGame ID, Placement IDsSeparate iOS/Android credentials
ironSourceApp KeySingle credential for all formats
VungleApp ID, Placement IDsSeparate reporting dashboard

Reporting & Analytics

Key Metrics

MetricDescriptionFormula
ARPDAUAverage Revenue Per Daily Active UserDaily revenue ÷ Daily active users
eCPMEffective Cost Per Mille (Revenue per 1000 impressions)(Revenue ÷ Impressions) × 1000
Fill RatePercentage of ad requests that receive an ad(Impressions ÷ Requests) × 100
CTRClick-Through Rate(Clicks ÷ Impressions) × 100
Completion RatePercentage of video ads watched to completion(Completions ÷ Starts) × 100

Accessing Reports

  1. Log in to AppLovin Dashboard
  2. Select your app
  3. Navigate to “Reporting” section
  4. Select desired date range
  5. Choose metrics to display
  6. Filter by ad format, network, country, etc.
  7. Export data if needed (CSV, Excel)

Real-time Monitoring

  1. Use “Analytics” tab for real-time data
  2. Set up alerts for performance drops
  3. Monitor network-specific issues
  4. Track mediation performance

Optimization Best Practices

Ad Implementation

TipImpact
Preload ads before showing themReduces user wait time
Implement smart retries with exponential backoffImproves fill rate
Test ad placements extensivelyImproves user experience
Cache ads when possibleFaster display, better user experience
Implement proper lifecycle managementPrevents memory leaks, crashes

Revenue Optimization

TipImpact
Enable MAX bidding for all supported networks10-30% revenue increase
Test frequency caps to find optimal balanceBalances user experience and revenue
Optimize waterfall for non-bidding networks5-15% revenue increase
Implement A/B testing for ad strategiesData-driven optimization
Monitor eCPM trends by networkIdentify opportunities for adjustment

User Experience

TipImpact
Avoid ads during critical gameplayReduces negative reviews
Clearly indicate rewarded valueIncreases completion rate
Implement loading indicators for adsSets user expectations
Respect natural break points in app flowImproves user retention
Gradually introduce ad formats to new usersBetter long-term engagement

Common Issues & Troubleshooting

Ad Not Showing

Possible CauseSolution
Ad not loadedEnsure ad.isReady() returns true before showing
Test mode enabledCheck if device is in test mode in dashboard
No fillImplement retry logic with backoff
Network issuesCheck device connectivity
Ad limit reachedCheck frequency cap settings

SDK Integration Issues

IssueSolution
Compatibility conflictsCheck for duplicate ad SDKs or version conflicts
Missing dependenciesReview required dependencies in documentation
ProGuard issues (Android)Add proper ProGuard rules
Thread exceptionsEnsure ad operations run on main thread
Initialization failureVerify SDK key is correct

Testing Ads

MethodHow To
Test modeEnable in dashboard for specific devices
Test adsUse special test ad units for d
Scroll to Top