本指南适用于使用 Google 移动广告 SDK 植入开屏广告的发布商。
开屏广告是一种特殊的广告格式,适合希望通过应用加载屏幕创收的发布商。开屏广告在用户将您的应用切换为在前台运行时展示,用户可随时关闭。
开屏广告会自动在一个较小的区域内展示您的品牌信息,让用户知道他们是在您的应用中。以下是一个开屏广告示例:

前提条件
- 通读入门指南。
务必用测试广告进行测试
在构建和测试应用时,请确保使用的是测试广告,而不是实际投放的广告。否则,可能会导致您的账号被中止。
对于开屏广告,加载测试广告最简便的方法就是使用下面的测试专用广告单元 ID:
ca-app-pub-3940256099942544/9257395921
该测试广告单元 ID 已经过专门配置,可确保每个请求返回的都是测试广告。您可以在自己应用的编码、测试和调试过程中随意使用该测试广告单元 ID。需要注意的一点是,请务必在发布应用前用您的广告单元 ID 替换该测试广告单元 ID。
如需详细了解 Google 移动广告 SDK 的测试广告如何运作,请参阅启用测试广告。
扩展 Application 类
创建一个扩展 Application 类的新类。这提供了一种可感知生命周期的方式来管理与应用状态(而非单个 Activity)相关联的广告:
Java
public class MyApplication extends Application
    implements ActivityLifecycleCallbacks, DefaultLifecycleObserver {
  private AppOpenAdManager appOpenAdManager;
  private Activity currentActivity;
  @Override
  public void onCreate() {
    super.onCreate();
    this.registerActivityLifecycleCallbacks(this);
    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    appOpenAdManager = new AppOpenAdManager();
  }
Kotlin
class MyApplication :
  MultiDexApplication(), Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {
  private lateinit var appOpenAdManager: AppOpenAdManager
  private var currentActivity: Activity? = null
  override fun onCreate() {
    super<MultiDexApplication>.onCreate()
    registerActivityLifecycleCallbacks(this)
    ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    appOpenAdManager = AppOpenAdManager()
  }
接下来,将以下代码添加到您的 AndroidManifest.xml 中:
<!-- TODO: Update to reference your actual package name. -->
<application
    android:name="com.google.android.gms.example.appopendemo.MyApplication" ...>
...
</application>
实现实用程序组件
您的广告应该要快速展示,因此最好先加载广告,以备需要展示时使用。这样一来,用户进入您的应用后,广告便可以立即展示。
实现一个实用程序组件 AppOpenAdManager,以封装与加载和展示开屏广告相关的任务:
Java
private class AppOpenAdManager {
  private static final String LOG_TAG = "AppOpenAdManager";
  private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/9257395921";
  private AppOpenAd appOpenAd = null;
  private boolean isLoadingAd = false;
  private boolean isShowingAd = false;
  /** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
  private long loadTime = 0;
  /** Constructor. */
  public AppOpenAdManager() {}
Kotlin
private inner class AppOpenAdManager {
  private var appOpenAd: AppOpenAd? = null
  private var isLoadingAd = false
  var isShowingAd = false
  /** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
  private var loadTime: Long = 0
若要使用 AppOpenAdManager,请调用单例 MyApplication 实例中的公共封装容器方法。Application 类会与其余代码进行交互,将加载和展示广告的任务委托给该管理器。
加载广告
下一步是填充 loadAd() 方法并处理广告加载回调函数。
Java
Kotlin
将 AD_UNIT_ID 替换为您自己的广告单元 ID。
展示广告
若要植入开屏广告,最常见的做法是在接近应用启动时尝试展示开屏广告;如果广告尚未就绪,则启动应用内容,并预加载另一个广告以备下次展示开屏广告。如需查看植入示例,请参阅开屏广告指南。
以下代码演示了如何展示广告并随后重新加载广告:
Java
public void showAdIfAvailable(
    @NonNull final Activity activity,
    @NonNull OnShowAdCompleteListener onShowAdCompleteListener) {
  // If the app open ad is already showing, do not show the ad again.
  if (isShowingAd) {
    Log.d(TAG, "The app open ad is already showing.");
    return;
  }
  // If the app open ad is not available yet, invoke the callback then load the ad.
  if (appOpenAd == null) {
    Log.d(TAG, "The app open ad is not ready yet.");
    onShowAdCompleteListener.onShowAdComplete();
    // Load an ad.
    return;
  }
  isShowingAd = true;
  appOpenAd.show(activity);
}
Kotlin
fun showAdIfAvailable(activity: Activity, onShowAdCompleteListener: OnShowAdCompleteListener) {
  // If the app open ad is already showing, do not show the ad again.
  if (isShowingAd) {
    Log.d(TAG, "The app open ad is already showing.")
    return
  }
  // If the app open ad is not available yet, invoke the callback then load the ad.
  if (appOpenAd == null) {
    Log.d(TAG, "The app open ad is not ready yet.")
    onShowAdCompleteListener.onShowAdComplete()
    // Load an ad.
    return
  }
  isShowingAd = true
  appOpenAd?.show(activity)
}
设置 FullScreenContentCallback
FullScreenContentCallback 负责处理与展示 AppOpenAd 相关的事件。在展示 AppOpenAd 之前,请务必按如下方法设置回调函数:
Java
appOpenAd.setFullScreenContentCallback(
    new FullScreenContentCallback() {
      @Override
      public void onAdDismissedFullScreenContent() {
        // Called when full screen content is dismissed.
        Log.d(TAG, "Ad dismissed fullscreen content.");
        // Don't forget to set the ad reference to null so you
        // don't show the ad a second time.
        appOpenAd = null;
        isShowingAd = false;
        onShowAdCompleteListener.onShowAdComplete();
        // Load an ad.
      }
      @Override
      public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) {
        // Called when full screen content failed to show.
        Log.d(TAG, adError.getMessage());
        appOpenAd = null;
        // Don't forget to set the ad reference to null so you
        // don't show the ad a second time.
        isShowingAd = false;
        onShowAdCompleteListener.onShowAdComplete();
        // Load an ad.
      }
      @Override
      public void onAdShowedFullScreenContent() {
        Log.d(TAG, "Ad showed fullscreen content.");
      }
      @Override
      public void onAdImpression() {
        // Called when an impression is recorded for an ad.
        Log.d(TAG, "The ad recorded an impression.");
      }
      @Override
      public void onAdClicked() {
        // Called when ad is clicked.
        Log.d(TAG, "The ad was clicked.");
      }
    });
Kotlin
appOpenAd?.fullScreenContentCallback =
  object : FullScreenContentCallback() {
    override fun onAdDismissedFullScreenContent() {
      // Called when full screen content is dismissed.
      Log.d(TAG, "Ad dismissed fullscreen content.")
      // Don't forget to set the ad reference to null so you
      // don't show the ad a second time.
      appOpenAd = null
      isShowingAd = false
      onShowAdCompleteListener.onShowAdComplete()
      // Load an ad.
    }
    override fun onAdFailedToShowFullScreenContent(adError: AdError) {
      // Called when full screen content failed to show.
      Log.d(TAG, adError.message)
      // Don't forget to set the ad reference to null so you
      // don't show the ad a second time.
      appOpenAd = null
      isShowingAd = false
      onShowAdCompleteListener.onShowAdComplete()
      // Load an ad.
    }
    override fun onAdShowedFullScreenContent() {
      Log.d(TAG, "Ad showed fullscreen content.")
    }
    override fun onAdImpression() {
      // Called when an impression is recorded for an ad.
      Log.d(TAG, "The ad recorded an impression.")
    }
    override fun onAdClicked() {
      // Called when ad is clicked.
      Log.d(TAG, "The ad was clicked.")
    }
  }
考虑广告有效期
为确保您不会展示过期的广告,请在 AppOpenAdManager 中添加一个方法,用于检查广告引用加载后经过了多长时间。这样,就可以使用该方法检查广告是否仍然有效。
Java
/** Check if ad was loaded more than n hours ago. */
private boolean wasLoadTimeLessThanNHoursAgo(long numHours) {
  long dateDifference = (new Date()).getTime() - loadTime;
  long numMilliSecondsPerHour = 3600000;
  return (dateDifference < (numMilliSecondsPerHour * numHours));
}
/** Check if ad exists and can be shown. */
private boolean isAdAvailable() {
  // For time interval details, see: https://support.google.com/admob/answer/9341964
  return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4);
}
Kotlin
/** Check if ad was loaded more than n hours ago. */
private fun wasLoadTimeLessThanNHoursAgo(numHours: Long): Boolean {
  val dateDifference: Long = Date().time - loadTime
  val numMilliSecondsPerHour: Long = 3600000
  return dateDifference < numMilliSecondsPerHour * numHours
}
/** Check if ad exists and can be shown. */
private fun isAdAvailable(): Boolean {
  // For time interval details, see: https://support.google.com/admob/answer/9341964
  return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4)
}
跟踪当前 activity
您需要 Activity 上下文才能展示广告。若要跟踪正在使用的最新 activity,请注册并实现 Application.ActivityLifecycleCallbacks。
Java
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {}
@Override
public void onActivityStarted(@NonNull Activity activity) {
  // An ad activity is started when an ad is showing, which could be AdActivity class from Google
  // SDK or another activity class implemented by a third party mediation partner. Updating the
  // currentActivity only when an ad is not showing will ensure it is not an ad activity, but the
  // one that shows the ad.
  if (!appOpenAdManager.isShowingAd) {
    currentActivity = activity;
  }
}
@Override
public void onActivityResumed(@NonNull Activity activity) {}
@Override
public void onActivityPaused(@NonNull Activity activity) {}
@Override
public void onActivityStopped(@NonNull Activity activity) {}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {}
Kotlin
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {
  // An ad activity is started when an ad is showing, which could be AdActivity class from Google
  // SDK or another activity class implemented by a third party mediation partner. Updating the
  // currentActivity only when an ad is not showing will ensure it is not an ad activity, but the
  // one that shows the ad.
  if (!appOpenAdManager.isShowingAd) {
    currentActivity = activity
  }
}
override fun onActivityResumed(activity: Activity) {}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
registerActivityLifecycleCallbacks 可用于监听所有 Activity 事件。通过监听 activity 启动和销毁的时间,您可以跟踪对当前 Activity 的引用,随后将其用于展示您的开屏广告。
监听应用进入前台事件
若要监听应用进入前台事件,请执行以下步骤:
将库添加到 Gradle 文件中
若要在发生应用进入前台的事件时收到通知,您需要注册一个 DefaultLifecycleObserver。然后,将其依赖项添加到应用级 build 文件中:
Kotlin
dependencies { implementation("com.google.android.gms:play-services-ads:24.7.0") implementation("androidx.lifecycle:lifecycle-process:2.8.3") }
Groovy
dependencies { implementation 'com.google.android.gms:play-services-ads:24.7.0' implementation 'androidx.lifecycle:lifecycle-process:2.8.3' }
实现生命周期观察器接口
您可以通过实现 DefaultLifecycleObserver 接口来监听进入前台事件。
实现 onStart() 以展示开屏广告。
Java
@Override
public void onStart(@NonNull LifecycleOwner owner) {
  DefaultLifecycleObserver.super.onStart(owner);
  // Show the ad (if available) when the app moves to foreground.
  appOpenAdManager.showAdIfAvailable(currentActivity);
}
Kotlin
override fun onStart(owner: LifecycleOwner) {
  super.onStart(owner)
  currentActivity?.let {
    // Show the ad (if available) when the app moves to foreground.
    appOpenAdManager.showAdIfAvailable(it)
  }
}
冷启动和加载屏幕
到现在为止,本文档都假定您仅在以下情况下展示开屏广告:用户将在内存中挂起的应用切换为在前台运行。用户启动您的应用,但该应用之前未在内存中挂起,这种情况就称为“冷启动”。
例如,用户首次打开您的应用便属于冷启动。对于冷启动,您没有之前已加载的开屏广告可供立即展示。请求广告和收到相应广告之间的延迟会导致出现以下情况:用户能够暂时使用您的应用,然后突然看到一条无关广告。应避免出现这种情况,因为这会导致用户体验不佳。
在冷启动时使用开屏广告的首选方法是,使用加载屏幕来加载游戏或应用资源,并且仅在加载屏幕中展示广告。如果您的应用已加载完毕,并且用户已经看到应用的主要内容,则不要展示广告。
最佳做法
借助开屏广告,您可以在用户首次启动应用和切换应用期间通过应用的加载屏幕变现,不过,还请务必考虑一些最佳做法,以便保持良好的应用使用体验。最佳做法如下所示:
- 在用户使用几次您的应用后,再展示第一个开屏广告。
- 在用户等待您的应用加载时展示开屏广告。
- 如果开屏广告之下有加载屏幕,并且加载屏幕在用户关闭广告之前已加载完毕,您可能需要通过 onAdDismissedFullScreenContent()方法关闭加载屏幕。
GitHub 示例
后续步骤
探索以下主题: