React Native Google Mobile Ads激励广告真机崩溃,模拟器正常求助
问题分析与解决方案
可能的原因及对应修复方法
1. 全局广告实例引发的生命周期冲突
你当前在组件外部创建rewarded广告实例,会导致实例在组件卸载后仍留存,组件重新挂载时重复绑定事件易引发内存泄漏或冲突,真机环境下这类问题更易触发崩溃。
修复方案:将广告实例创建移至组件内部,用useRef保存实例避免重复创建:
import React, { useState, useEffect, useRef } from "react"; import { View, Button, Text, ScrollView } from 'react-native' import { RewardedAd, RewardedAdEventType, TestIds } from 'react-native-google-mobile-ads'; const adUnitId = __DEV__ ? TestIds.REWARDED : 'ca-app-pub-3940256099942544/5224354917'; const Testing = ({ navigation }) =>{ const [loaded, setLoaded] = useState(false); const rewardedAdRef = useRef(null); useEffect(() => { rewardedAdRef.current = RewardedAd.createForAdRequest(adUnitId, { requestNonPersonalizedAdsOnly: true, keywords: ['fashion', 'clothing'], }); const unsubscribeLoaded = rewardedAdRef.current.addAdEventListener(RewardedAdEventType.LOADED, () => { setLoaded(true); rewardedAdRef.current.show(); }); const unsubscribeEarned = rewardedAdRef.current.addAdEventListener( RewardedAdEventType.EARNED_REWARD, reward => { console.log('User earned reward of ', reward); }, ); rewardedAdRef.current.load(); return () => { unsubscribeLoaded(); unsubscribeEarned(); if (rewardedAdRef.current) { rewardedAdRef.current.destroy(); } }; }, []); return ( <ScrollView> <View style={{flex:1, justifyContent : 'center',alignItems : 'center'}}> <Text> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, </Text> <Button onPress = {() => navigation.navigate('First')} title='Next Screen'></Button> </View> </ScrollView> ) } export default Testing;
2. 广告加载后立即show()的时机问题
真机环境下广告加载完成时机可能与UI渲染不同步,直接在LOADED事件中调用show()易阻塞UI线程引发崩溃。
修复方案:改为用户交互触发广告展示:
// 替换原useEffect中的LOADED事件逻辑 const [adLoaded, setAdLoaded] = useState(false); const unsubscribeLoaded = rewardedAdRef.current.addAdEventListener(RewardedAdEventType.LOADED, () => { setAdLoaded(true); }); // 修改return部分的UI return ( <ScrollView> <View style={{flex:1, justifyContent : 'center',alignItems : 'center', padding: 20}}> <Text> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, </Text> {adLoaded && ( <Button onPress={() => { rewardedAdRef.current.show(); setAdLoaded(false); }} title='观看广告获取奖励' style={{marginVertical: 10}} /> )} <Button onPress = {() => navigation.navigate('First')} title='Next Screen'></Button> </View> </ScrollView> )
3. 真机平台配置缺失或依赖不兼容
横幅广告正常但激励广告崩溃,可能是Android/iOS平台的Google Ads配置不全,或依赖版本不匹配。
Android端检查点
- 确认
android/build.gradle中Google服务版本与插件兼容:buildscript { dependencies { classpath 'com.google.gms:google-services:4.3.15' } } - 检查
AndroidManifest.xml是否包含必要权限:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
iOS端检查点
- 执行
pod install后重启项目,确保依赖安装完整; - 检查
Info.plist是否添加广告配置:<key>GADApplicationIdentifier</key> <string>ca-app-pub-3940256099942544~1458002511</string> <key>SKAdNetworkItems</key> <array> <dict> <key>SKAdNetworkIdentifier</key> <string>cstr6suwn9.skadnetwork</string> </dict> </array>
4. 测试广告ID的判断逻辑问题
部分真机环境下__DEV__判断可能失效,导致加载正式广告ID(未审核的正式广告在真机可能无法加载甚至崩溃)。
修复方案:开发阶段强制使用测试ID:
// 开发阶段固定用测试ID,上线前再替换为正式ID const adUnitId = TestIds.REWARDED;
5. 缺失错误事件监听
当前代码未监听广告加载、展示失败的事件,无法定位崩溃原因。
修复方案:添加错误监听捕获异常:
// 在useEffect中新增以下监听 const unsubscribeLoadFailed = rewardedAdRef.current.addAdEventListener( RewardedAdEventType.FAILED_TO_LOAD, error => { console.log('广告加载失败:', error); }, ); const unsubscribeShowFailed = rewardedAdRef.current.addAdEventListener( RewardedAdEventType.SHOW_FAILED, error => { console.log('广告展示失败:', error); }, ); // 清理时移除监听 return () => { unsubscribeLoaded(); unsubscribeEarned(); unsubscribeLoadFailed(); unsubscribeShowFailed(); rewardedAdRef.current?.destroy(); };
内容的提问来源于stack exchange,提问作者Rahul Aadam
相关产品推荐
相关产品推荐

