android-reverse-engineering.../plugins/android-reverse-engineering/skills/ad-analysis/references/ad-format-patterns.md

6.9 KiB

Ad Format Patterns

Code patterns for each ad format across major SDKs — how to identify banner, interstitial, rewarded, native, and app-open ads in decompiled code.

Banner Ads

Small ads displayed within the app UI, typically at top or bottom of screen.

Lifecycle

  1. Create ad view (XML layout or programmatic)
  2. Set ad unit ID
  3. Load ad request
  4. Ad displays inline — auto-refreshes periodically

SDK-specific patterns

AdMob:

AdView adView = new AdView(context);
adView.setAdSize(AdSize.BANNER); // or LARGE_BANNER, MEDIUM_RECTANGLE, FULL_BANNER, LEADERBOARD
adView.setAdUnitId("ca-app-pub-XXXXX/YYYYY");
adView.loadAd(new AdRequest.Builder().build());

Unity Ads:

BannerView bannerView = new BannerView(activity, "placement_id", new UnityBannerSize(320, 50));
bannerView.load();

IronSource:

IronSource.loadBanner(bannerLayout, "placement_name");
// or LevelPlay:
LevelPlayBannerAdView banner = new LevelPlayBannerAdView(context, "ad_unit_id");
banner.loadAd();

AppLovin MAX:

MaxAdView adView = new MaxAdView("ad_unit_id", context);
adView.loadAd();
adView.startAutoRefresh();

Meta AN:

AdView adView = new AdView(context, "placement_id", AdSize.BANNER_HEIGHT_50);
adView.loadAd();

Grep for all banners

grep -rn 'AdView\|BannerView\|AdSize\.\|BANNER\|loadBanner\|IronSourceBannerLayout\|MaxAdView\|MBBannerView\|PAGBannerAd\|InMobiBanner' "$SOURCE_DIR"

Interstitial Ads

Full-screen ads shown at natural transition points (level complete, between pages).

Lifecycle

  1. Load ad in advance (preload)
  2. Check if ad is ready
  3. Show ad at transition point
  4. Handle close callback → resume app flow

SDK-specific patterns

AdMob:

InterstitialAd.load(context, "ca-app-pub-XXXXX/YYYYY", adRequest,
    new InterstitialAdLoadCallback() {
        @Override public void onAdLoaded(InterstitialAd ad) { /* cache */ }
        @Override public void onAdFailedToLoad(LoadAdError error) { /* retry */ }
    });
// Show:
interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() { ... });
interstitialAd.show(activity);

Unity Ads:

UnityAds.load("placement_id", new IUnityAdsLoadListener() { ... });
UnityAds.show(activity, "placement_id", new IUnityAdsShowListener() { ... });

IronSource:

IronSource.loadInterstitial();
if (IronSource.isInterstitialReady()) {
    IronSource.showInterstitial("placement_name");
}

AppLovin MAX:

MaxInterstitialAd interstitialAd = new MaxInterstitialAd("ad_unit_id", activity);
interstitialAd.loadAd();
interstitialAd.showAd();

Grep for all interstitials

grep -rn 'InterstitialAd\|showInterstitial\|loadInterstitial\|MaxInterstitialAd\|isInterstitialReady\|FullScreenContentCallback\|TTFullScreenVideoAd\|PAGInterstitialAd' "$SOURCE_DIR"

Rewarded Ads

Full-screen ads that give the user an in-app reward for watching.

Lifecycle

  1. Load ad in advance
  2. Show ad when user opts in (e.g., "Watch ad for extra life")
  3. User watches ad to completion
  4. Reward callback fires → grant reward
  5. Handle incomplete views (user skipped)

SDK-specific patterns

AdMob:

RewardedAd.load(context, "ca-app-pub-XXXXX/YYYYY", adRequest,
    new RewardedAdLoadCallback() {
        @Override public void onAdLoaded(RewardedAd ad) { /* cache */ }
    });
// Show:
rewardedAd.show(activity, new OnUserEarnedRewardListener() {
    @Override public void onUserEarnedReward(RewardItem reward) {
        int amount = reward.getAmount();
        String type = reward.getType();
    }
});

Unity Ads:

// Same load/show as interstitial, but placement configured as rewarded on dashboard
UnityAds.load("rewarded_placement", loadListener);
UnityAds.show(activity, "rewarded_placement", showListener);
// Reward granted in onUnityAdsShowComplete with UnityAds.UnityAdsShowCompletionState.COMPLETED

IronSource:

// Auto-loaded by default
if (IronSource.isRewardedVideoAvailable()) {
    IronSource.showRewardedVideo("placement_name");
}
// Reward in RewardedVideoListener.onRewardedVideoAdRewarded(Placement placement)

AppLovin MAX:

MaxRewardedAd rewardedAd = MaxRewardedAd.getInstance("ad_unit_id", activity);
rewardedAd.loadAd();
rewardedAd.showAd(); // reward via MaxRewardedAdListener.onUserRewarded(MaxAd, MaxReward)

Grep for all rewarded

grep -rn 'RewardedAd\|RewardedVideo\|showRewardedVideo\|OnUserEarnedRewardListener\|RewardItem\|MaxRewardedAd\|TTRewardVideoAd\|PAGRewardedAd\|MBRewardVideoHandler' "$SOURCE_DIR"

Native Ads

Ads that match the app's look and feel, rendered with custom templates.

Lifecycle

  1. Create ad loader with ad unit ID
  2. Load ad
  3. Receive native ad object with assets (headline, body, image, CTA, icon)
  4. Inflate custom layout and bind assets
  5. Register ad view for impression/click tracking

SDK-specific patterns

AdMob:

AdLoader adLoader = new AdLoader.Builder(context, "ca-app-pub-XXXXX/YYYYY")
    .forNativeAd(nativeAd -> { /* bind to NativeAdView */ })
    .withNativeAdOptions(new NativeAdOptions.Builder().build())
    .build();
adLoader.loadAd(new AdRequest.Builder().build());

Meta AN:

NativeAd nativeAd = new NativeAd(context, "placement_id");
nativeAd.loadAd(nativeAd.buildLoadAdConfig()
    .withAdListener(new NativeAdListener() { ... })
    .build());

AppLovin MAX:

MaxNativeAdLoader nativeAdLoader = new MaxNativeAdLoader("ad_unit_id", context);
nativeAdLoader.setNativeAdListener(new MaxNativeAdListener() { ... });
nativeAdLoader.loadAd();

Grep for all native

grep -rn 'NativeAd\|NativeAdView\|NativeAdLoader\|AdLoader\.Builder\|NativeBannerAd\|NativeAdLayout\|MaxNativeAdLoader\|InMobiNative\|VungleNativeAd' "$SOURCE_DIR"

App Open Ads

Full-screen ads shown when the app is foregrounded (cold start or resume from background).

Lifecycle

  1. Preload ad during app initialization or background
  2. On app foreground, check if ad is available and not expired
  3. Show ad before the main content appears
  4. Handle close callback → show app content

Pattern (AdMob-specific)

AppOpenAd.load(context, "ca-app-pub-XXXXX/YYYYY", adRequest,
    AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
    new AppOpenAd.AppOpenAdLoadCallback() {
        @Override public void onAdLoaded(AppOpenAd ad) { /* cache with timestamp */ }
    });
// Show on foreground:
appOpenAd.show(activity);

Common implementation pattern uses Application.ActivityLifecycleCallbacks to detect foreground transitions:

registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
    @Override public void onActivityStarted(Activity activity) {
        // Show app open ad if available
    }
});

Grep for app open

grep -rn 'AppOpenAd\|AppOpenAdLoadCallback\|APP_OPEN_AD\|AppOpenAdManager\|appOpenAd' "$SOURCE_DIR"