> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adrop.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Splash Ads

> Learn how to implement splash ads in your Flutter app.

## Overview

Splash ads are displayed on the splash screen when the app launches. The ad appears alongside your app logo, providing a natural user experience.

### Features

* Natural ad exposure at app launch
* Maintains brand image with app logo
* Fixed ad size: 360dp × 270dp (Android), 360px × 270px (iOS)
* Supports image ads

<Note>
  Use the test unit ID during development: `PUBLIC_TEST_UNIT_ID_SPLASH`
</Note>

***

## Caching Behavior

Splash ads are prefetched and cached on the device so the creative can appear instantly at launch, before any network request completes. On the next launch the cached creative is shown first, and a fresh ad request runs in the background to refresh the cache for subsequent launches.

<Warning>
  Because of this prefetch model, a creative that is **paused** in Ad Control Console may still be shown from the device cache until the next refresh cycle completes on each user's device. Plan creative pauses and replacements with a buffer for the cache to roll over across the install base.
</Warning>

***

## Implementation

Splash ads in Flutter apps are implemented through native platform configurations. Since splash ads display before the Flutter engine fully initializes, they must be configured at the native Android and iOS level.

<Info>
  Flutter apps use native splash screens that appear before Flutter loads. Adrop splash ads integrate with this native splash flow.
</Info>

***

## Android Configuration

### Step 1: Configure strings.xml

Add the following settings to `android/app/src/main/res/values/strings.xml`.

```xml title="android/app/src/main/res/values/strings.xml" theme={null}
<resources>
    <!-- App name -->
    <string name="app_name">My App</string>

    <!-- Splash ad unit ID -->
    <string name="adrop_splash_ad_unit_id" translatable="false">YOUR_SPLASH_UNIT_ID</string>

    <!-- Activity to navigate to after splash ends -->
    <string name="adrop_splash_ad_next_activity" translatable="false">com.yourcompany.yourapp.MainActivity</string>
</resources>
```

<Note>
  Use `PUBLIC_TEST_UNIT_ID_SPLASH` instead of `YOUR_SPLASH_UNIT_ID` for testing.
</Note>

### Step 2: Add Splash Logo Image

Add your app logo to the `android/app/src/main/res/drawable/` folder.

```
android/app/src/main/res/drawable/splash_logo.png
```

Recommended size: 288dp × 288dp (@2x: 576px, @3x: 864px)

### Step 3: Configure AndroidManifest.xml

Set `AdropSplashAdActivity` as the launcher activity.

```xml title="android/app/src/main/AndroidManifest.xml" theme={null}
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:name="${applicationName}"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher">

        <!-- Splash Ad Activity -->
        <activity
            android:name="io.adrop.ads.splash.AdropSplashAdActivity"
            android:theme="@style/LaunchTheme"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Main Activity (Flutter) -->
        <activity
            android:name=".MainActivity"
            android:exported="false"
            android:launchMode="singleTop"
            android:taskAffinity=""
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <meta-data
                android:name="io.flutter.embedding.android.NormalTheme"
                android:resource="@style/NormalTheme" />
        </activity>

    </application>
</manifest>
```

<Warning>
  `android:exported="true"` is required for `AdropSplashAdActivity`. Make sure to remove the launcher intent-filter from `MainActivity`.
</Warning>

### Step 4: Configure Splash Theme

Add or update the splash theme in `android/app/src/main/res/values/styles.xml`.

```xml title="android/app/src/main/res/values/styles.xml" theme={null}
<resources>
    <!-- Launch theme with splash screen -->
    <style name="LaunchTheme" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@android:color/white</item>
        <item name="windowSplashScreenAnimatedIcon">@drawable/splash_logo</item>
        <item name="postSplashScreenTheme">@style/NormalTheme</item>
    </style>

    <!-- Normal theme -->
    <style name="NormalTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <item name="android:windowBackground">?android:colorBackground</item>
    </style>
</resources>
```

### Step 5: Customize Layout (Optional)

To use a custom layout, create `activity_adrop_splash_ad.xml` in `android/app/src/main/res/layout/`.

```xml title="android/app/src/main/res/layout/activity_adrop_splash_ad.xml" theme={null}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:paddingHorizontal="24dp"
    android:fitsSystemWindows="true">

    <!-- App logo (center) -->
    <ImageView
        android:src="@drawable/splash_logo"
        android:layout_width="288dp"
        android:layout_height="288dp"
        android:scaleType="fitXY"
        android:layout_centerInParent="true"/>

    <!-- Ad area (bottom) - Required -->
    <ImageView
        android:id="@+id/adrop_splash_ad_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"/>
</RelativeLayout>
```

<Warning>
  An `ImageView` with `android:id="@+id/adrop_splash_ad_image"` is required. The ad will be displayed in this view.
</Warning>

### Step 6: Configure Display Duration (Optional)

To change the default display duration, create `android/app/src/main/res/values/integers.xml`.

```xml title="android/app/src/main/res/values/integers.xml" theme={null}
<resources>
    <!-- Ad request timeout (milliseconds, 500~3000) -->
    <integer name="adrop_splash_ad_request_timeout">1000</integer>

    <!-- Ad display duration (milliseconds, 500~3000) -->
    <integer name="adrop_splash_ad_max_timeout">2000</integer>
</resources>
```

### Step 7: Implement AdropSplashAd Listener (Optional)

To receive splash ad events, set up a listener in your `Application` class.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import android.app.Application
  import io.adrop.ads.Adrop
  import io.adrop.ads.splash.AdropSplashAd
  import io.adrop.ads.splash.AdropSplashAdListener
  import io.adrop.ads.model.AdropErrorCode

  class MainApplication : Application() {
      private lateinit var splashAd: AdropSplashAd

      override fun onCreate() {
          super.onCreate()

          // Initialize SDK
          Adrop.initialize(this, production = false)

          // Configure splash ad
          splashAd = AdropSplashAd(this) { splashAd ->
              // shouldSkip: Determines whether to skip splash ad
              // Return true to skip the ad and go directly to the main screen
              checkShouldSkipSplash()
          }

          splashAd.splashAdListener = object : AdropSplashAdListener {
              override fun onAdReceived(ad: AdropSplashAd) {
                  println("Splash ad received successfully")
              }

              override fun onAdFailedToReceive(ad: AdropSplashAd, errorCode: AdropErrorCode) {
                  println("Failed to receive splash ad: $errorCode")
              }

              override fun onAdImpression(ad: AdropSplashAd) {
                  println("Splash ad impression")
              }

              override fun onAdClose(ad: AdropSplashAd, impressed: Boolean) {
                  println("Splash ad closed - impressed: $impressed")
              }
          }
      }

      private fun checkShouldSkipSplash(): Boolean {
          // Example: Skip splash when entering via deep link or under certain conditions
          return false
      }
  }
  ```

  ```java Java theme={null}
  import android.app.Application;
  import io.adrop.ads.Adrop;
  import io.adrop.ads.splash.AdropSplashAd;
  import io.adrop.ads.splash.AdropSplashAdListener;
  import io.adrop.ads.model.AdropErrorCode;

  public class MainApplication extends Application {
      private AdropSplashAd splashAd;

      @Override
      public void onCreate() {
          super.onCreate();

          // Initialize SDK
          Adrop.INSTANCE.initialize(this, false, new String[]{});

          // Configure splash ad
          splashAd = new AdropSplashAd(this, ad -> checkShouldSkipSplash());

          splashAd.setSplashAdListener(new AdropSplashAdListener() {
              @Override
              public void onAdReceived(AdropSplashAd ad) {
                  System.out.println("Splash ad received successfully");
              }

              @Override
              public void onAdFailedToReceive(AdropSplashAd ad, AdropErrorCode errorCode) {
                  System.out.println("Failed to receive splash ad: " + errorCode);
              }

              @Override
              public void onAdImpression(AdropSplashAd ad) {
                  System.out.println("Splash ad impression");
              }

              @Override
              public void onAdClose(AdropSplashAd ad, boolean impressed) {
                  System.out.println("Splash ad closed - impressed: " + impressed);
              }
          });
      }

      private boolean checkShouldSkipSplash() {
          // Determine whether to skip splash ad
          return false;
      }
  }
  ```
</CodeGroup>

<Note>
  When `shouldSkip` returns `true`, the ad is not loaded and navigates immediately to the main screen.
</Note>

***

## iOS Configuration

### Step 1: Configure AppDelegate

Update your `ios/Runner/AppDelegate.swift` to display splash ads.

```swift title="ios/Runner/AppDelegate.swift" theme={null}
import UIKit
import Flutter
import AdropAds

@main
@objc class AppDelegate: FlutterAppDelegate {
    var splashAdViewController: AdropSplashAdViewController?

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)

        // Initialize Adrop SDK
        Adrop.initialize(production: false)

        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}
```

### Step 2: Configure SceneDelegate (iOS 13+)

For apps using SceneDelegate, update `ios/Runner/SceneDelegate.swift`.

```swift title="ios/Runner/SceneDelegate.swift" theme={null}
import UIKit
import Flutter
import AdropAds

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let windowScene = (scene as? UIWindowScene) else { return }

        window = UIWindow(windowScene: windowScene)

        #if DEBUG
        let splashUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"
        #else
        let splashUnitId = "YOUR_PRODUCTION_SPLASH_UNIT_ID"
        #endif

        // Create splash ad view controller
        let splashViewController = AdropSplashAdViewController(
            unitId: splashUnitId
        )
        splashViewController.logoImage = UIImage(named: "splash_logo")
        splashViewController.delegate = self

        // Set main view controller to transition to after splash
        splashViewController.mainViewController = FlutterViewController(engine: FlutterEngine(name: "main"), nibName: nil, bundle: nil)

        window?.rootViewController = splashViewController
        window?.makeKeyAndVisible()
    }
}

// MARK: - AdropSplashAdDelegate
extension SceneDelegate: AdropSplashAdDelegate {
    func onAdClose(_ ad: AdropSplashAd, impressed: Bool) {
        print("Splash ad closed - impressed: \(impressed)")
    }

    func onAdReceived(_ ad: AdropSplashAd) {
        print("Splash ad received")
    }

    func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
        print("Splash ad failed: \(errorCode)")
    }

    func onAdImpression(_ ad: AdropSplashAd) {
        print("Splash ad impression")
    }
}
```

### Step 3: Add Logo Image

Add your app logo to the iOS assets:

1. Open Xcode and navigate to `Runner/Assets.xcassets`
2. Add a new Image Set named `splash_logo`
3. Add your logo images (@1x, @2x, @3x)

Recommended size: 200×200 \~ 300×300 points

### Step 4: Configure Info.plist (Optional)

If using SceneDelegate, ensure your `Info.plist` has the scene configuration:

```xml title="ios/Runner/Info.plist" theme={null}
<key>UIApplicationSceneManifest</key>
<dict>
    <key>UIApplicationSupportsMultipleScenes</key>
    <false/>
    <key>UISceneConfigurations</key>
    <dict>
        <key>UIWindowSceneSessionRoleApplication</key>
        <array>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>Default Configuration</string>
                <key>UISceneDelegateClassName</key>
                <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
            </dict>
        </array>
    </dict>
</dict>
```

***

## AdropSplashAdDelegate

| Method                      | Required | Description                                                             |
| --------------------------- | -------- | ----------------------------------------------------------------------- |
| `onAdClose(_:impressed:)`   | Optional | Called when splash ad closes. `impressed` indicates if ad was displayed |
| `onAdReceived(_:)`          | Optional | Called when ad is received successfully                                 |
| `onAdFailedToReceive(_:_:)` | Optional | Called when ad fails to receive                                         |
| `onAdImpression(_:)`        | Optional | Called when ad impression is recorded                                   |

***

## Best Practices

### 1. Set Appropriate Timers

Configure reasonable timeout values for better user experience.

```xml theme={null}
<!-- Android: integers.xml -->
<integer name="adrop_splash_ad_request_timeout">1000</integer>
<integer name="adrop_splash_ad_max_timeout">2000</integer>
```

```swift theme={null}
// iOS (deprecated — set the splash ad duration in the Adrop console instead)
splashViewController.displayDuration = 3.0
```

### 2. Optimize Logo Image

Prepare your app logo in appropriate sizes to minimize loading time.

**Android:**

```
drawable-mdpi/splash_logo.png    (192px × 192px)
drawable-hdpi/splash_logo.png    (288px × 288px)
drawable-xhdpi/splash_logo.png   (384px × 384px)
drawable-xxhdpi/splash_logo.png  (576px × 576px)
drawable-xxxhdpi/splash_logo.png (768px × 768px)
```

**iOS:**

```
splash_logo@1x.png  (200px × 200px)
splash_logo@2x.png  (400px × 400px)
splash_logo@3x.png  (600px × 600px)
```

### 3. Handle Failures Gracefully

Ensure the app starts normally even when ad loading fails.

```swift theme={null}
func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
    print("Ad load failed: \(errorCode)")
    // AdropSplashAdViewController automatically calls onAdClose
}
```

### 4. Distinguish Test/Production Environments

```swift theme={null}
#if DEBUG
let splashUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"
let isProduction = false
#else
let splashUnitId = "YOUR_PRODUCTION_SPLASH_UNIT_ID"
let isProduction = true
#endif

Adrop.initialize(production: isProduction)

let splashViewController = AdropSplashAdViewController(unitId: splashUnitId)
splashViewController.logoImage = UIImage(named: "splash_logo")
```

***

## Testing

### Test Unit ID

Use the test unit ID during development.

```
PUBLIC_TEST_UNIT_ID_SPLASH
```

<Warning>
  Make sure to use the actual unit ID created in the Adrop console for production releases. No ad revenue is generated with test unit IDs.
</Warning>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Splash screen is not displayed (Android)">
    * Verify that `AdropSplashAdActivity` is set as LAUNCHER in AndroidManifest.xml
    * Check `android:exported="true"` setting
    * Verify SDK initialization is complete
    * Ensure `adrop_service.json` is in the `android/app/src/main/assets` folder
  </Accordion>

  <Accordion title="Splash screen is not displayed (iOS)">
    * Verify `window.rootViewController` is set correctly
    * Check if SceneDelegate is configured in Info.plist
    * Ensure SDK initialization is complete
    * Verify `adrop_service.json` is added to the Xcode project
  </Accordion>

  <Accordion title="Ad is not loading">
    * Check network connection status
    * Verify the unit ID is correct
    * Confirm `production: false` setting in test environment
    * Check error code in `onAdFailedToReceive`
  </Accordion>

  <Accordion title="Not transitioning to Flutter app">
    * Verify `adrop_splash_ad_next_activity` is set correctly (Android)
    * Check `onAdClose` delegate implementation (iOS)
    * Ensure FlutterViewController is created properly
  </Accordion>

  <Accordion title="Custom layout not applied (Android)">
    * Verify filename is exactly `activity_adrop_splash_ad.xml`
    * Check that ImageView with `@+id/adrop_splash_ad_image` exists
    * Clean build and re-run (Build > Clean Project > Rebuild)
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Interstitial Ads" href="/sdk/flutter/interstitial">
    Display full-screen ads during screen transitions
  </Card>

  <Card title="Banner Ads" href="/sdk/flutter/banner">
    Implement banner ads
  </Card>

  <Card title="Native Ads" href="/sdk/flutter/native">
    Custom design native ads
  </Card>

  <Card title="Rewarded Ads" href="/sdk/flutter/rewarded">
    Provide user rewards
  </Card>
</CardGroup>
