加载单个开屏广告

开屏广告会在用户打开或返回您的应用时展示。用户可以随时关闭开屏广告。如需通过应用加载界面创收,请使用开屏广告。有关详情,请参阅

开屏广告指南和最佳实践。

本指南介绍了如何将开屏广告植入到 React Native 原生应用中。

前提条件

在继续操作之前,请确保满足以下条件:

Android

ca-app-pub-3940256099942544/9257395921

iOS

ca-app-pub-3940256099942544/5575463023

加载广告

如需加载开屏广告,请调用 load 方法。

以下示例会在成功时加载开屏广告,在失败时记录错误:

export async function loadAppOpenAd(
  adUnitId: string,
): Promise<AppOpenAd | null> {
  try {
    const ad = await AppOpenAd.load({adUnitId});
    return ad;
  } catch (error) {
    const loadError = error as LoadAdError;
    console.error('Failed to load app open ad:', loadError.message);
    return null;
  }
}

监听广告事件

在展示广告之前,请在已加载的 AppOpenAd 实例上设置 adEventCallback 监听器。此监听器会接收广告生命周期事件的回调,例如广告在屏幕上展示或用户点按广告。如需了解可用的回调,请参阅 AdEventCallback。

以下示例设置了用于监听广告事件的回调:

export function registerAdEvents(ad: AppOpenAd) {
  ad.adEventCallback = {
    // Called when the ad is presented on screen.
    onAdShowedFullScreenContent: () => {
      console.log('App open ad showed full screen content.');
    },
    // Called when the ad is closed by the user.
    onAdDismissedFullScreenContent: () => {
      console.log('App open ad dismissed full screen content.');
      ad.destroy();
    },
    // Called when presentation fails.
    onAdFailedToShowFullScreenContent: (error) => {
      console.error('Failed to show app open ad:', error);
      ad.destroy();
    },
    // Called when an impression is recorded.
    onAdImpression: () => {
      console.log('App open ad recorded an impression.');
    },
    // Called when the user taps the ad.
    onAdClicked: () => {
      console.log('App open ad was clicked.');
    },
    // Called when the ad is estimated to have earned money.
    onAdPaid: (adValue) => {
      console.log(
        `App open ad paid: ${adValue.amountMicros} ${adValue.currencyCode}`,
      );
    },
  };
}

此示例还会在用户关闭广告或广告无法展示时使用 destroy 方法。此过程会释放广告使用的资源。

展示广告

如需展示开屏广告,请调用 show 方法:

export function showAppOpenAd(ad: AppOpenAd) {
  ad.show();
}

通过应用级管理工具管理广告

我们建议您在 React 组件树之外的应用级管理器中管理开屏广告。由于开屏广告会在用户打开或返回您的应用时全局展示,因此应用级管理器会将广告与界面分开。

以下示例创建了一个 SingleLoadAppOpenAdManager 实例,该实例会加载广告、监听广告事件并检查广告可用性:

export class SingleLoadAppOpenAdManager {
  private ad: AppOpenAd | null = null;
  private loadTime = 0;
  private isShowingAd = false;

  async loadAd(adUnitId: string) {
    // Avoid re-loading if an ad is already loaded or showing.
    if (this.ad) {
      return;
    }
    try {
      this.ad = await AppOpenAd.load({adUnitId});
      this.loadTime = Date.now();
      this.ad.adEventCallback = {
        onAdDismissedFullScreenContent: () => {
          this.ad?.destroy();
          this.ad = null;
          this.isShowingAd = false;
          // Preload the next ad for future foreground transitions.
          this.loadAd(adUnitId);
        },
        onAdFailedToShowFullScreenContent: () => {
          // An ad object that fails to present is consumed and cannot be reused.
          // Clean up native resources and preload a new ad for future events.
          this.ad?.destroy();
          this.ad = null;
          this.isShowingAd = false;
          this.loadAd(adUnitId);
        },
      };
    } catch (error) {
      console.error('Failed to load app open ad:', error);
    }
  }

  showAdIfAvailable() {
    if (!this.ad || !this.isAdAvailable()) {
      console.warn(
        'App open ad cannot be shown: ad is not loaded or has expired.',
      );
      return;
    }
    if (this.isShowingAd) {
      console.warn('App open ad cannot be shown: an ad is already displaying.');
      return;
    }

    this.ad.show();
    this.isShowingAd = true;
  }

  isAdAvailable(): boolean {
    // App Open ads expire after 4 hours per Google Mobile Ads policy.
    const FOUR_HOURS_IN_MS = 4 * 60 * 60 * 1000;
    return this.ad !== null && Date.now() - this.loadTime < FOUR_HOURS_IN_MS;
  }
}

应用级管理员可帮助您执行以下操作:

  • 使广告状态独立于屏幕导航和组件生命周期。
  • 跟踪原生线程事件中的广告展示状态。
  • 处理应用前台转换,避免重复展示广告。
  • 在后台预加载广告,以便在应用打开时展示广告。
  • 请检查 4 小时的广告过期限制,以免展示过期的广告。
  • 将加载、展示和清理广告资源的操作结合起来。

监听应用进入前台事件

如需在应用返回前台时展示广告,请使用 AppState 模块在应用的根目录(例如 App.tsx 文件)中监听应用状态变化。执行以下操作:

  1. 为 'change' 事件注册 AppState 监听器。
  2. 当状态转换为 'active' 状态时,请对广告管理器实例调用 showAdIfAvailable 方法。

以下示例会监听应用进入前台事件,并在有广告可用时展示广告:

export function setupAppOpenAdForegroundListener(adManager: {
  showAdIfAvailable: () => void;
}): NativeEventSubscription {
  return AppState.addEventListener('change', (nextAppState: AppStateStatus) => {
    if (nextAppState === 'active') {
      adManager.showAdIfAvailable();
    }
  });
}

了解冷启动和加载屏幕

当应用从头开始启动时,就会发生冷启动,例如,用户首次打开应用时,或者设备关闭应用以释放内存后。在冷启动期间,您没有预先加载好的开屏广告可供接下来展示。

由于广告请求延迟,用户可能会在广告展示之前与您的应用互动。为避免造成不佳的用户体验,请仅在应用素材资源加载期间,在加载屏幕中展示冷启动开屏广告。如果素材资源已加载完毕,并且用户在广告加载之前已看到主要内容,则不要展示广告。

设置测试屏幕

如需以交互方式测试广告或在特定屏幕上展示广告,请在组件状态中管理广告实例。

以下示例使用 useEffect 清理钩子将开屏广告集成到 React Native 组件中。如果组件在广告展示之前卸载,此钩子会释放原生资源。

export function AppOpenSingleLoadScreen() {
  const [ad, setAd] = useState<AppOpenAd | null>(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [status, setStatus] = useState<string>('Idle');

  useEffect(() => {
    return () => {
      ad?.destroy();
    };
  }, [ad]);

  const handleLoad = async () => {
    setStatus('Loading App Open ad...');
    const loadedAd = await loadAppOpenAd(APP_OPEN_AD_UNIT_ID);
    if (loadedAd) {
      registerAdEvents(loadedAd);
      const onDismiss =
        loadedAd.adEventCallback?.onAdDismissedFullScreenContent;
      loadedAd.adEventCallback = {
        ...loadedAd.adEventCallback,
        onAdDismissedFullScreenContent: () => {
          onDismiss?.();
          setStatus('Ad dismissed.');
        },
      };
      setAd((prevAd) => {
        prevAd?.destroy();
        return loadedAd;
      });
      setIsLoaded(true);
      setStatus('App Open ad loaded!');
    } else {
      setStatus('Failed to load App Open ad.');
    }
  };

  const handleShow = () => {
    if (ad) {
      showAppOpenAd(ad);
      setIsLoaded(false);
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>App Open Ad</Text>
      <Text style={styles.status}>Status: {status}</Text>
      <View style={styles.buttonGroup}>
        <Button title="Load Ad" onPress={handleLoad} />
        <View style={styles.spacerSmall} />
        <Button title="Show Ad" onPress={handleShow} disabled={!isLoaded} />
      </View>
    </View>
  );
}

后续步骤

植入开屏广告后,请探索以下主题: