Select platform: [Android](https://developers.google.com/admob/android/next-gen/rewarded "View this page for the Android platform documentation.") [iOS](https://developers.google.com/admob/ios/rewarded "View this page for the iOS platform documentation.") [Unity](https://developers.google.com/admob/unity/rewarded "View this page for the Unity platform documentation.") [Flutter](https://developers.google.com/admob/flutter/rewarded "View this page for the Flutter platform documentation.") [Android (Legacy)](https://developers.google.com/admob/android/rewarded "View this page for the Android (Legacy) platform documentation.")

<br />

[Rewarded ads](https://support.google.com/admob/answer/7372450) let you reward users with in-app items for interacting with video ads, playable ads, and surveys.

<br />

This guide explains how to integrate rewarded ads into an Android app.

## Before you begin

Before you continue, do the following:

- [Set up GMA Next-Gen SDK](https://developers.google.com/admob/android/next-gen/quick-start).
- Use the test rewarded ad unit ID `ca-app-pub-3940256099942544/5224354917`.
  - When building and testing your app, make sure that you use test ads rather than live, production ads. If you don't use the test ad unit ID, Google can suspend your account.
  - Before you publish your app, replace this ID with your ad unit ID.
  - For details on GMA Next-Gen SDK test ads, see [Enable test ads](https://developers.google.com/admob/android/next-gen/test-ads).

## Understand ad preloading (beta)

[Video](https://www.youtube.com/watch?v=gtCvIEGOwtA)

Ad preloading in GMA Next-Gen SDK automates ad loading and caching.

Ad preloading provides the following benefits:

- **Reference management**: maintains references until ads are shown.
- **Automatic reloading**: loads a new ad when one is retrieved from the cache.
- **Managed retries**: loads a new ad when one fails to load.
- **Expiration handling**: refreshes ads before expiring.
- **Cache optimization**: optimizes the cache order to deliver the highest priority ad.

Note: To load ads manually, see [Load a single rewarded ad](https://developers.google.com/admob/android/next-gen/rewarded/single-load).

## Start ad preloading

To begin preloading ads, call the `start` method once at
app start. After you call the `start` method,
GMA Next-Gen SDK automatically preloads ads and retries failed requests for
preloaded configurations.

The following example shows how to start preloading ads:


### Kotlin

    val adRequest = AdRequest.Builder(adUnitId).build()
    val preloadConfig = PreloadConfiguration(adRequest)
    RewardedAdPreloader.start(adUnitId, preloadConfig)

### Java

    AdRequest adRequest = new AdRequest.Builder(adUnitId).build();
    PreloadConfiguration preloadConfig = new PreloadConfiguration(adRequest);
    RewardedAdPreloader.start(adUnitId, preloadConfig);

<br />

Replace <var class="readonly" translate="no">AD_UNIT_ID</var> with your ad unit ID.

The previous example shows how to use the ad unit ID as the preload ID. A
preload ID is a string identifier that you create to identify an ad preloading
configuration. If your app requires multiple targeting configurations for the
same ad unit ID, pass a custom string identifier.

## Get and show the preloaded ad

When you want to show an ad, call the `pollAd` method.
GMA Next-Gen SDK retrieves an available ad and automatically preloads the next ad
in the background. If no ad is available, GMA Next-Gen SDK returns no ads.
When you have an available ad object, call the `show` method to display the ad. Use a reward listener to handle reward events. The following example shows how to retrieve and show a preloaded ad:


### Kotlin

    private fun pollAndShowAd(activity: Activity, adUnitId: String) {
      // Polling returns the next available ad and loads another ad in the background.
      val ad = RewardedAdPreloader.pollAd(adUnitId)
      if (ad == null) {
        Log.e(TAG, "Rewarded ad is not available.")
        return
      }

      // Interact with the ad object as needed.
      Log.d(TAG, "Rewarded ad response info: ${ad.getResponseInfo()}")
      ad.adEventCallback =
        object : RewardedAdEventCallback {
          override fun onAdImpression() {
            Log.d(TAG, "Rewarded ad recorded an impression.")
          }
        }
      ad.show(activity) { rewardItem -> Log.d(TAG, "User earned reward: ${rewardItem.amount}") }
    }

### Java

    private void pollAndShowAd(Activity activity, String adUnitId) {
      // Polling returns the next available ad and loads another ad in the background.
      final RewardedAd ad = RewardedAdPreloader.pollAd(adUnitId);

      // Interact with the ad object as needed.
      if (ad == null) {
        Log.e(TAG, "Rewarded ad is not available.");
        return;
      }

      Log.d(TAG, "Rewarded ad response info: " + ad.getResponseInfo());
      ad.setAdEventCallback(
          new RewardedAdEventCallback() {
            @Override
            public void onAdImpression() {
              Log.d(TAG, "Rewarded ad recorded an impression.");
            }
          });

      // Show the ad.
      ad.show(
          activity,
          rewardItem -> {
            Log.d(TAG, "User earned reward: " + rewardItem.getAmount());
          });
    }

<br />

Until you are ready to show an ad, avoid calling the `pollAd`
method. To read the ad response info without showing it,
see [Read the response info](https://developers.google.com/admob/android/next-gen/rewarded#peek-at-ad).

## Listen to ad events

Before showing the ad, listen to ad events. The following example
registers callbacks for ad events:


### Kotlin

```kotlin
private fun listenToAdEvents() {
  // Listen for ad events.
  val ad = rewardedAd
  if (ad == null) {
    Log.e(TAG, "Rewarded ad is not ready yet.")
    return
  }

  ad.adEventCallback =
    object : RewardedAdEventCallback {
      override fun onAdShowedFullScreenContent() {
        // Rewarded ad did show.
      }

      override fun onAdDismissedFullScreenContent() {
        // Rewarded ad did dismiss.
        rewardedAd = null
      }

      override fun onAdFailedToShowFullScreenContent(
        fullScreenContentError: FullScreenContentError
      ) {
        // Rewarded ad failed to show.
        Log.e(TAG, "Rewarded ad failed to show: ${fullScreenContentError.message}")
      }

      override fun onAdImpression() {
        // Rewarded ad did record an impression.
      }

      override fun onAdClicked() {
        // Rewarded ad did record a click.
      }
    }
}
```

### Java

```java
private void listenToAdEvents() {
  // Listen for ad events.
  if (rewardedAd == null) {
    Log.e(TAG, "Rewarded ad is not ready yet.");
    return;
  }

  rewardedAd.setAdEventCallback(
      new RewardedAdEventCallback() {
        @Override
        public void onAdShowedFullScreenContent() {
          // Rewarded ad did show.
        }

        @Override
        public void onAdDismissedFullScreenContent() {
          // Rewarded ad did dismiss.
          rewardedAd = null;
        }

        @Override
        public void onAdFailedToShowFullScreenContent(
            FullScreenContentError fullScreenContentError) {
          // Rewarded ad failed to show.
          Log.e(TAG, "Rewarded ad failed to show: " + fullScreenContentError.getMessage());
        }

        @Override
        public void onAdImpression() {
          // Rewarded ad did record an impression.
        }

        @Override
        public void onAdClicked() {
          // Rewarded ad did record a click.
        }
      });
}
```

<br />

## Optional: Validate server-side verification (SSV) callbacks

If your app requires extra data in
[server-side verification](https://developers.google.com/admob/android/next-gen/ssv)

callbacks, use the custom data feature of ads. Google ad servers pass any
string value set on an ad object to the `custom_data` query parameter of the
SSV callback. If no custom data value is set, the `custom_data` query
parameter value isn't present in the SSV callback.

The following example sets custom data on an ad object before
showing the ad:


### Kotlin

    RewardedAd.load(
      context,
      AD_UNIT_ID,
      AdRequest.Builder().build(),
      object : RewardedAdLoadCallback() {
        override fun onAdLoaded(ad: RewardedAd) {
          rewardedAd = ad
    val options =
    ServerSideVerificationOptions.Builder().setCustomData("SAMPLE_CUSTOM_DATA_STRING").build()
    rewardedAd?.setServerSideVerificationOptions(options)
    }
    },
    )

### Java

    RewardedAd.load(
        context,
        AD_UNIT_ID,
        new AdRequest.Builder().build(),
        new RewardedAdLoadCallback() {
          @Override
          public void onAdLoaded(RewardedAd ad) {
            rewardedAd = ad;
    ServerSideVerificationOptions options =
    new ServerSideVerificationOptions.Builder()
    .setCustomData("SAMPLE_CUSTOM_DATA_STRING")
    .build();
    rewardedAd.setServerSideVerificationOptions(options);
          }
        });

<br />

Replace `SAMPLE_CUSTOM_DATA_STRING` with your custom
data.

> [!IMPORTANT]
> **Key Point:** The custom reward string is [percent escaped](https://en.wikipedia.org/wiki/Percent-encoding). You might need to decode the custom reward string when you parse it from the SSV callback.

## Optional: Listen to preloading events

When you start preloading ads, register for preload events to get notified
when ads are preloaded successfully, fail to preload, or the ad cache is
exhausted.

The following example shows how to register for preloading ad events:


### Kotlin

```kotlin
val preloadCallback =
  object : PreloadCallback {
    override fun onAdFailedToPreload(preloadId: String, adError: LoadAdError) {
      Log.d(TAG, "Rewarded preload ad $preloadId failed to load with error: ${adError.message}")
    }

    override fun onAdsExhausted(preloadId: String) {
      Log.i(TAG, "Rewarded preload ad $preloadId is not available")
    }

    override fun onAdPreloaded(preloadId: String, responseInfo: ResponseInfo) {
      Log.i(TAG, "Rewarded preload ad $preloadId is available")
    }
  }
val adRequest = AdRequest.Builder(adUnitId).build()
val preloadConfig = PreloadConfiguration(adRequest)
RewardedAdPreloader.start(adUnitId, preloadConfig, preloadCallback)
```

### Java

```java
PreloadCallback preloadCallback =
    new PreloadCallback() {
      @Override
      public void onAdFailedToPreload(String preloadId, LoadAdError adError) {
        Log.d(
            TAG,
            String.format(
                "Rewarded preload ad %s failed to load with error: %s",
                preloadId, adError.getMessage()));
      }

      @Override
      public void onAdsExhausted(String preloadId) {
        Log.i(TAG, "Rewarded preload ad " + preloadId + " is not available");
      }

      @Override
      public void onAdPreloaded(String preloadId, ResponseInfo responseInfo) {
        Log.i(TAG, "Rewarded preload ad " + preloadId + " is available");
      }
    };

AdRequest adRequest = new AdRequest.Builder(adUnitId).build();
PreloadConfiguration preloadConfig = new PreloadConfiguration(adRequest);
RewardedAdPreloader.start(adUnitId, preloadConfig, preloadCallback);
```

<br />

When an ad fails to load, GMA Next-Gen SDK automatically preloads ads and retries
failed requests for preloaded configurations.

## Optional: Check for ad availability

If you need to know whether an ad is available, check for ad availability. The
following example checks whether a preloaded ad is available:


### Kotlin

```kotlin
private fun isAdAvailable(adUnitId: String): Boolean {
  return RewardedAdPreloader.isAdAvailable(adUnitId)
}
```

### Java

```java
private boolean isAdAvailable(String adUnitId) {
  return RewardedAdPreloader.isAdAvailable(adUnitId);
}
```

<br />

## Optional: Set the buffer size

The buffer size controls the number of preloaded ads held in memory. By default,
Google optimizes buffer size to balance memory consumption and ad serving
latency. You can set a custom buffer size to increase the number of ads kept in
memory. We recommend a buffer size of two preloaded ads.

The following example shows how to set a buffer size:


### Kotlin

```kotlin
val adRequest = AdRequest.Builder(adUnitId).build()
// Define a PreloadConfiguration and set the buffer size to 2 preloaded ads.
val preloadConfig = PreloadConfiguration(adRequest, bufferSize = 2)
RewardedAdPreloader.start(adUnitId, preloadConfig)
```

### Java

```java
AdRequest adRequest = new AdRequest.Builder(adUnitId).build();
// Define a PreloadConfiguration and set the buffer size to 2 preloaded ads.
PreloadConfiguration preloadConfig = new PreloadConfiguration(adRequest, 2);
RewardedAdPreloader.start(adUnitId, preloadConfig);
```

<br />

### Preload cache limits

GMA Next-Gen SDK enforces an app-wide limit on the total number of preloaded ads
across all ad units and preload IDs:

- Default limit: Google holds a maximum of six preloaded ads in memory. This limit is shared across all formats and preload IDs.
- We recommend keeping a buffer size of two for each preload ID.

> [!NOTE]
> **Note:** If your app can benefit from an increased app-wide limit, contact your account manager to request an increase.

## Optional: Stop preloading ads

If you don't need to show ads for a specific preload ID again in the session,
you can stop preloading ads. To stop loading ads for a specific preload ID,
call the `destroy` method with a preload ID. Calling the
`destroy` method removes all preloaded ads associated
with the preload ID from the cache.

The following example shows how to stop preloading ads:


### Kotlin

```kotlin
private fun stopPreloading(adUnitId: String) {
  // Stops the preloading and destroy preloaded ads.
  RewardedAdPreloader.destroy(adUnitId)
}
```

### Java

```java
private void stopPreloading(String adUnitId) {
  // Stops the preloading and destroy preloaded ads.
  RewardedAdPreloader.destroy(adUnitId);
}
```

<br />

## Optional: Read the response info

Read the next preloaded ad's response info without removing the ad from the
cache.

The following example shows how to read the next preloaded ad response info:


### Kotlin

```kotlin
val responseInfo = RewardedAdPreloader.peekAdResponseInfo(preloadId)
if (responseInfo == null) {
  Log.e(TAG, "Failed to peek ad response info.")
  return
}

Log.d(TAG, "Peeked ad response ID: ${responseInfo.responseId}")
```

### Java

```java
ResponseInfo responseInfo = RewardedAdPreloader.peekAdResponseInfo(preloadId);
if (responseInfo == null) {
  Log.e(TAG, "Failed to peek ad response info.");
  return;
}

Log.d(TAG, "Peeked ad response ID: " + responseInfo.getResponseId());
```

<br />