You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Native中Google Mobile Ads的RewardedInterstitialAd仅首次可用,后续尝试无限加载

React Native中Google Mobile Ads的RewardedInterstitialAd仅首次可用,后续尝试无限加载

兄弟,我之前做React Native项目时也踩过这个一模一样的坑!第一次广告正常弹出,后面点下载就一直转圈圈,查了半天才搞懂问题出在哪,给你分享几个必试的解决办法:

核心问题:RewardedInterstitialAd是「一次性实例」

你得先搞明白:每一个RewardedInterstitialAd实例只能被加载和展示一次,展示完成后这个实例就“报废”了,不能再用来发起新的加载请求。很多人踩坑就是因为反复用同一个旧实例去加载,自然会无限转圈。

具体解决步骤

1. 广告关闭后立刻重新加载新广告

在用户关闭广告的回调里,马上触发新的广告加载,这样下次用户点击下载时,广告已经提前准备好,不会出现加载等待的情况。

给你贴一段我自己在用的代码示例:

import React, { useState, useEffect, useRef } from "react";
import { View, Pressable, Image, StyleSheet, Modal, ActivityIndicator } from "react-native";
import { RewardedInterstitialAd, AdEventType, TestIds } from 'react-native-google-mobile-ads';

export default function DownloadScreen() {
  // 开发环境用测试ID,正式环境替换成你的真实广告单元ID
  const AD_UNIT_ID = __DEV__ ? TestIds.REWARDED_INTERSTITIAL : 'ca-app-pub-你的ID/你的ID';
  // 用ref保存广告是否加载完成的状态
  const isAdLoaded = useRef(false);
  // 用ref保存广告实例
  let adInstance = useRef(null);

  // 封装广告加载函数
  const loadNewAd = () => {
    // 每次加载都创建全新的广告实例!
    adInstance.current = RewardedInterstitialAd.createForAdRequest(AD_UNIT_ID, {
      requestNonPersonalizedAdsOnly: true,
    });

    // 监听广告加载成功事件
    const loadSuccessListener = adInstance.current.addAdEventListener(AdEventType.LOADED, () => {
      isAdLoaded.current = true;
      loadSuccessListener(); // 加载成功后取消监听,避免内存泄漏
    });

    // 监听广告加载失败事件(一定要加,能帮你排查隐性问题)
    const loadErrorListener = adInstance.current.addAdEventListener(AdEventType.ERROR, (error) => {
      console.log('广告加载炸了:', error);
      isAdLoaded.current = false;
      loadErrorListener();
    });

    // 监听广告关闭事件,关闭后立刻加载下一个广告
    const adDismissedListener = adInstance.current.addAdEventListener(AdEventType.DISMISSED, () => {
      isAdLoaded.current = false;
      loadNewAd(); // 提前加载好下一次要用的广告
      adDismissedListener();
    });

    // 发起加载请求
    adInstance.current.load();
  };

  // 组件挂载时加载第一个广告
  useEffect(() => {
    loadNewAd();
    // 组件卸载时清理广告实例
    return () => {
      if (adInstance.current) {
        adInstance.current.destroy();
      }
    };
  }, []);

  // 处理下载按钮点击
  const handleDownloadImage = () => {
    if (isAdLoaded.current) {
      // 广告已加载,展示广告
      adInstance.current.show().then(() => {
        // 广告展示成功,这里写你的图片下载逻辑
        console.log('开始下载图片啦');
        // 比如调用你的downloadImage()函数
      }).catch((err) => {
        console.log('广告展示失败:', err);
      });
    } else {
      // 广告还在加载,给用户个提示
      console.log('广告正在路上,稍等一下~');
      // 可以在这里显示ActivityIndicator
    }
  };

  // 你的组件渲染逻辑
  return (
    <View style={styles.container}>
      <Pressable style={styles.downloadBtn} onPress={handleDownloadImage}>
        <Image source={{ uri: '你的图片地址' }} style={styles.image} />
      </Pressable>
      {!isAdLoaded.current && <ActivityIndicator size="small" color="#0000ff" />}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  downloadBtn: {
    padding: 10,
  },
  image: {
    width: 200,
    height: 200,
  },
});

2. 千万别重用旧的广告实例

很多新手会把广告实例声明在组件外部,或者用同一个变量反复赋值,但旧实例在展示后就处于“已消耗”状态,再调用load()根本不会生效。一定要每次加载都用RewardedInterstitialAd.createForAdRequest()创建新实例。

3. 排查隐性错误

你说没有错误提示,那大概率是没加AdEventType.ERROR的监听!加上之后就能看到具体的错误信息,比如:

  • 测试环境用了真实广告ID,被AdMob限流
  • 广告单元ID配置错误
  • 网络问题导致广告请求失败

额外提醒

  • 开发阶段一定要用Google提供的测试ID,用真实ID频繁请求会被限流,导致广告加载失败
  • 确保你的react-native-google-mobile-ads是最新版本,旧版本确实存在过这种“仅首次可用”的bug
  • 如果用了Modal弹窗,要确保广告展示时Modal的状态处理正确,不要影响广告的生命周期

备注:内容来源于stack exchange,提问作者Aakash Maurya

火山引擎 最新活动