> ## 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 React Native 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 React Native apps are implemented through native platform configurations. Since splash ads display before the React Native bridge fully initializes, they must be configured at the native Android and iOS level.

<Info>
  React Native apps use native splash screens that appear before the JavaScript bundle 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=".MainApplication"
        android:label="@string/app_name"
        android:icon="@mipmap/ic_launcher"
        android:allowBackup="false"
        android:theme="@style/AppTheme">

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

        <!-- Main Activity (React Native) -->
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
            android:launchMode="singleTask"
            android:windowSoftInputMode="adjustResize"
            android:exported="false">
        </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>
    <!-- App theme -->
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
    </style>

    <!-- Splash theme (Android 12+) -->
    <style name="SplashTheme" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@android:color/white</item>
        <item name="windowSplashScreenAnimatedIcon">@drawable/splash_logo</item>
        <item name="postSplashScreenTheme">@style/AppTheme</item>
    </style>
</resources>
```

<Note>
  The `androidx.core:core-splashscreen` dependency is included in the Adrop SDK. No additional setup is required.
</Note>

### 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>

### Step 8: Running the App

When running the Android app with React Native CLI, you need to specify the main activity:

```bash theme={null}
npx react-native run-android --main-activity io.adrop.ads.splash.AdropSplashAdActivity
```

<Note>
  This is required because `AdropSplashAdActivity` is set as the launcher activity instead of `MainActivity`.
</Note>

***

## iOS Configuration

### Step 1: Configure AppDelegate

Update your `ios/YourApp/AppDelegate.mm` (or `AppDelegate.swift`) to display splash ads.

<CodeGroup>
  ```swift Swift theme={null}
  import UIKit
  import React
  import AdropAds

  @main
  class AppDelegate: UIResponder, UIApplicationDelegate {
      var window: UIWindow?

      func application(
          _ application: UIApplication,
          didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
      ) -> Bool {
          // Initialize Adrop SDK
          Adrop.initialize(production: false)

          return true
      }
  }
  ```

  ```objc Objective-C theme={null}
  #import "AppDelegate.h"
  #import <React/RCTBundleURLProvider.h>
  @import AdropAds;

  @implementation AppDelegate

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  {
      // Initialize Adrop SDK
      [Adrop initializeWithProduction:NO useInAppBrowser:NO targetCountries:@[]];

      self.moduleName = @"YourApp";
      self.initialProps = @{};

      return [super application:application didFinishLaunchingWithOptions:launchOptions];
  }

  @end
  ```
</CodeGroup>

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

For apps using SceneDelegate, create or update `ios/YourApp/SceneDelegate.swift`.

```swift title="ios/YourApp/SceneDelegate.swift" theme={null}
import UIKit
import React
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)

        // Create React Native root view
        let bridge = RCTBridge(delegate: self, launchOptions: nil)!
        let rootView = RCTRootView(bridge: bridge, moduleName: "YourApp", initialProperties: nil)
        let rootViewController = UIViewController()
        rootViewController.view = rootView

        #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.delegate = self
        splashViewController.logoImage = UIImage(named: "splash_logo")
        splashViewController.backgroundColor = .white
        splashViewController.mainViewController = rootViewController

        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")
    }
}
```

<Warning>
  `mainViewController` must be set. After the splash ad closes, the SDK transitions to this view controller to display the React Native app.
</Warning>

### Step 3: Add Logo Image

Add your app logo to the iOS assets:

1. Open Xcode and navigate to `YourApp/Images.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

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

```xml title="ios/YourApp/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>
```

<Note>
  On iOS, the splash ad display duration is configured in the Adrop console ad unit settings.
</Note>

### 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 isProduction = false
let splashUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"
#else
let isProduction = true
let splashUnitId = "YOUR_PRODUCTION_SPLASH_UNIT_ID"
#endif

Adrop.initialize(production: isProduction)
let splashViewController = AdropSplashAdViewController(unitId: splashUnitId)
```

***

## 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 React Native app">
    * Verify `adrop_splash_ad_next_activity` is set correctly (Android)
    * Check `onAdClose` delegate implementation (iOS)
    * Ensure RCTBridge and RCTRootView are 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
  </Accordion>
</AccordionGroup>

***

## Next Steps

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

  <Card title="Banner Ads" href="/sdk/react-native/banner">
    Implement banner ads
  </Card>

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

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