Flutter集成AdMob遇No fill加载失败错误求助
Flutter AdMob激励广告加载失败(错误码3/No fill)排查方案
我花了近2天在Flutter中集成AdMob,已完成以下配置:
- 在Manifest中配置官方测试APPLICATION_ID
- 使用文档提供的激励广告测试ID
- 初始化时添加了测试设备ID
等待1个月后仍持续报错,错误信息:
I/Ads ( 6953): Ad failed to load : 3 I/flutter ( 6953): RewardedAd failed to load: LoadAdError(code: 3, domain: com.google.android.gms.ads, message: No fill., responseInfo: ResponseInfo(responseId: null, mediationAdapterClassName: , adapterResponses: [], loadedAdapterResponseInfo: null), responseExtras: {})
我的配置与代码
Manifest配置
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-3940256099942544~3347511713"/>
main.dart代码
void main() { WidgetsFlutterBinding.ensureInitialized(); MobileAds.instance.initialize(); runApp(const MyApp()); }
广告页面代码
// ignore_for_file: prefer_const_constructors, file_names, avoid_print import 'dart:io'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:google_mobile_ads/google_mobile_ads.dart'; import 'package:park/src/Routes/Routes.dart'; class Ads extends StatefulWidget { const Ads({super.key}); @override State<Ads> createState() => _AdsState(); } class _AdsState extends State<Ads> { RewardedAd? _rewardedAd; int _numRewardedLoadAttempts = 0; int maxFailedLoadAttempts = 3; final adUnitId = Platform.isAndroid ? 'ca-app-pub-3940256099942544/5224354917' : 'ca-app-pub-3940256099942544/1712485313'; @override void initState() { super.initState(); MobileAds.instance.updateRequestConfiguration(RequestConfiguration( testDeviceIds: ['here i put my test device id'])); _createRewardedAd(); } void _createRewardedAd() { RewardedAd.load( adUnitId: adUnitId, request: AdRequest(), rewardedAdLoadCallback: RewardedAdLoadCallback( onAdLoaded: (RewardedAd ad) { print('$ad loaded.'); _rewardedAd = ad; _numRewardedLoadAttempts = 0; }, onAdFailedToLoad: (LoadAdError error) { print('RewardedAd failed to load: $error'); _rewardedAd = null; _numRewardedLoadAttempts += 1; if (_numRewardedLoadAttempts < maxFailedLoadAttempts) { _createRewardedAd(); } }, ), ); } void _showRewardedAd() { if (_rewardedAd == null) { print('Warning: attempt to show rewarded ad before loaded.'); return; } _rewardedAd!.fullScreenContentCallback = FullScreenContentCallback( onAdShowedFullScreenContent: (RewardedAd ad) => print('ad onAdShowedFullScreenContent.'), onAdDismissedFullScreenContent: (RewardedAd ad) { print('$ad onAdDismissedFullScreenContent.'); ad.dispose(); _createRewardedAd(); }, onAdFailedToShowFullScreenContent: (RewardedAd ad, AdError error) { print('$ad onAdFailedToShowFullScreenContent: $error'); ad.dispose(); _createRewardedAd(); }, ); _rewardedAd!.setImmersiveMode(true); _rewardedAd!.show( onUserEarnedReward: (AdWithoutView ad, RewardItem reward) { print('$ad with reward $RewardItem(${reward.amount}, ${reward.type})'); }, ); _rewardedAd = null; } @override void dispose() { _rewardedAd?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( decoration: const BoxDecoration( gradient: LinearGradient( colors: [Color(0xFF303030), Color(0xFF6B46C1), Color(0xFF303030)], begin: Alignment.topLeft, end: Alignment.bottomRight, stops: [0.05, 0.5, 1], ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ DefaultTextStyle( style: TextStyle( fontSize: 15, fontFamily: GoogleFonts.akatab().fontFamily, color: Colors.white, fontWeight: FontWeight.bold), child: Text('Reward Ad : $_numRewardedLoadAttempts'), ), SizedBox(height: 20), ElevatedButton( onPressed: _showRewardedAd, child: const Text('Get 1 Free score')), ElevatedButton( onPressed: () { Navigator.pushNamed(context, AppRoutes.home); }, child: const Text('Back'), ) ], ), ); } }
排查与修复方案
1. 确认测试设备ID是否正确
- 测试设备ID必须是当前运行设备的真实ID,可通过Logcat过滤
Ads标签,找到类似Use AdRequest.Builder.addTestDevice("DEVICE_ID")的日志,复制其中的ID替换代码中的占位符。 - 字符必须完全匹配,任何错误都会导致无法触发测试广告。
2. 优化广告初始化时机
目前初始化未等待完成就加载广告,可能导致请求异常,改为异步等待:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await MobileAds.instance.initialize(); runApp(const MyApp()); }
页面初始化时也需确保配置更新完成后再加载广告:
@override void initState() { super.initState(); _setupAds(); } Future<void> _setupAds() async { await MobileAds.instance.updateRequestConfiguration(RequestConfiguration( testDeviceIds: ['真实测试设备ID'])); _createRewardedAd(); }
3. 检查Google Play服务版本
- 确保测试设备上的Google Play服务为最新版本,旧版本可能无法正常请求测试广告。
- 可在设备「设置-应用-Google Play服务」中检查更新。
4. 验证网络环境
- 测试广告需要稳定网络,避免使用不稳定的VPN或代理,可切换移动数据/Wi-Fi测试。
5. 更新AdMob依赖版本
确保google_mobile_ads插件为最新版,过时版本可能存在已知问题:
dependencies: google_mobile_ads: ^最新版本号
执行flutter pub get完成更新。
6. 调整广告加载重试逻辑
当前重试无延迟易触发频率限制,添加指数退避延迟:
void _createRewardedAd() { RewardedAd.load( adUnitId: adUnitId, request: AdRequest(), rewardedAdLoadCallback: RewardedAdLoadCallback( onAdLoaded: (RewardedAd ad) { print('$ad loaded.'); _rewardedAd = ad; _numRewardedLoadAttempts = 0; }, onAdFailedToLoad: (LoadAdError error) { print('RewardedAd failed to load: $error'); _rewardedAd = null; _numRewardedLoadAttempts += 1; if (_numRewardedLoadAttempts < maxFailedLoadAttempts) { // 每次重试延迟翻倍,避免触发频率限制 Future.delayed(Duration(seconds: 2 * _numRewardedLoadAttempts), () { _createRewardedAd(); }); } }, ), ); }
内容的提问来源于stack exchange,提问作者Thanos Rom
相关产品推荐
相关产品推荐

