You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:44:53