React Native中如何在页面关闭/返回时展示Google Mobile Ads插屏广告
React Native 实现页面关闭时展示插屏广告(支持物理返回键)
需求描述
当用户关闭当前页面(包括通过设备物理返回键触发关闭)时,展示InterstitialAd插屏广告。
现有代码
Test组件代码
import React, { useState, useEffect } from "react"; import { View, Button, Text, ScrollView, } from 'react-native'; import { AppOpenAd, InterstitialAd, RewardedAd, BannerAd, TestIds, AdEventType } from 'react-native-google-mobile-ads'; const Test = ({ navigation }) => { useEffect(() => { let interstitial = InterstitialAd.createForAdRequest(TestIds.INTERSTITIAL, { requestNonPersonalizedAdsOnly: true, keywords: ['fashion', 'clothing'], }); interstitial.addAdEventListener(AdEventType.LOADED, () => { interstitial.show(); }); interstitial.load(); return () => { interstitialListener = null; }; }, []); return ( <ScrollView> <View> <View style={{ marginTop: 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> </View> </View> </ScrollView> ) } export default Test
App.js代码
import * as React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import Test from './Test'; import TestTwo from './TestTwo'; const Tab = createBottomTabNavigator(); const HomeTabs = ({ navigation }) =>{ return ( <Tab.Navigator screenOptions={{ headerShown: false }}> <Tab.Screen name="Test" component={Test} /> </Tab.Navigator> ); } const Stack = createNativeStackNavigator(); export default function App () { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Home" component={HomeTabs} /> <Tab.Screen name="TestTwo" component={TestTwo} /> </Stack.Navigator> </NavigationContainer> ); }
问题分析
现有代码存在以下问题:
- 组件挂载时立即加载并展示广告,不符合“页面关闭时展示”的需求
- 未处理设备物理返回键的监听逻辑
- 广告监听的清理方式不正确,可能导致内存泄漏
- 未结合React Navigation的页面生命周期事件触发广告
解决方案
结合React Navigation的页面生命周期事件和React Native的物理返回键监听,预加载广告后在页面关闭时触发展示。
修改后的Test组件代码
import React, { useState, useEffect } from "react"; import { View, Text, ScrollView, BackHandler } from 'react-native'; import { InterstitialAd, TestIds, AdEventType } from 'react-native-google-mobile-ads'; const Test = ({ navigation }) => { const [adLoaded, setAdLoaded] = useState(false); let interstitial = null; let backHandler = null; let navigationListener = null; useEffect(() => { // 创建插屏广告实例并预加载 interstitial = InterstitialAd.createForAdRequest(TestIds.INTERSTITIAL, { requestNonPersonalizedAdsOnly: true, keywords: ['fashion', 'clothing'], }); // 监听广告加载完成 const adListener = interstitial.addAdEventListener(AdEventType.LOADED, () => { setAdLoaded(true); }); // 监听广告加载失败 interstitial.addAdEventListener(AdEventType.FAILED_TO_LOAD, () => { setAdLoaded(false); }); // 启动广告加载 interstitial.load(); // 监听导航页面移除事件(捕获导航返回按钮触发) navigationListener = navigation.addListener('beforeRemove', (e) => { e.preventDefault(); handlePageClose(); }); // 监听物理返回键 backHandler = BackHandler.addEventListener('hardwareBackPress', () => { handlePageClose(); return true; // 阻止默认返回,手动处理 }); // 组件卸载时清理资源 return () => { adListener?.remove(); backHandler?.remove(); navigationListener?.(); interstitial = null; }; }, [navigation]); // 页面关闭逻辑 const handlePageClose = () => { if (adLoaded && interstitial) { // 展示广告,关闭后再返回 interstitial.addAdEventListener(AdEventType.CLOSED, () => { navigation.goBack(); interstitial.load(); // 重新加载广告以备下次使用 }); interstitial.show(); } else { // 广告未加载完成,直接返回 navigation.goBack(); } }; return ( <ScrollView> <View> <View style={{ marginTop: 20, paddingHorizontal: 16 }}> <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> </View> </View> </ScrollView> ) } export default Test
关键修改点说明
- 预加载广告:组件挂载时提前加载广告,确保页面关闭时广告已就绪
- 双场景监听:同时监听
beforeRemove导航事件和物理返回键,覆盖所有页面关闭场景 - 广告展示逻辑:页面关闭时优先展示已加载的广告,广告关闭后再执行返回操作;未加载完成则直接返回
- 资源清理:组件卸载时移除所有监听、销毁广告实例,避免内存泄漏
内容的提问来源于stack exchange,提问作者Rahul Aadam
相关产品推荐
相关产品推荐

