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




