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

Flutter使用google_mobile_ads时Android 11.0测试横幅广告无法加载

问题原因与解决方案

核心原因

  • Android 11 包可见性限制:Android 11(API 30)开始系统收紧了应用查询其他已安装应用的权限,谷歌移动广告SDK依赖Google Play服务完成广告加载,如果没有配置包可见性规则,SDK无法检测到Google Play服务,就会抛出内部错误(错误码0),而Android 9没有这项限制所以可以正常加载。
  • 广告渲染逻辑错误:你当前用_banner是否为空判断是否渲染AdWidget,但_banner实例创建完成不等于广告加载完成,AdWidget要求广告必须完成load回调后才能插入组件树,这就是你收到AdWidget requires Ad.load to be called before AdWidget is inserted into the tree报错的直接原因。

修复步骤

1. 补充AndroidManifest.xml配置

在AndroidManifest.xml的manifest根节点下,添加和application节点平级的包可见性声明,同时确认已配置网络权限:

<!-- 包可见性声明,适配Android 11及以上 -->
<queries>
    <package android:name="com.google.android.gms" />
</queries>

<!-- 确认已有网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />

<application ...>
    <!-- 原有AD应用ID配置保持不变 -->
    <meta-data
      android:name="com.google.android.gms.ads.APPLICATION_ID"
      android:value="ca-app-pub-MY_APP_ID"/>
</application>

2. 修正广告初始化与渲染逻辑

首先确保你已经在应用启动时初始化了MobileAds,推荐在main.dart的main方法中调用:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 初始化谷歌移动广告SDK
  await MobileAds.instance.initialize();
  runApp(MyApp());
}

然后修改页面的广告加载、监听与渲染逻辑:

// 页面内新增变量
BannerAd? _banner;
bool _isAdLoaded = false;

@override
void initState() {
  super.initState();
  _loadBannerAd();
}

void _loadBannerAd() {
  _banner = BannerAd(
    adUnitId: 'ca-app-pub-3940256099942544/6300978111',
    size: AdSize.fullBanner,
    request: const AdRequest(),
    listener: BannerAdListener(
      onAdLoaded: (Ad ad) {
        print('Ad loaded.');
        setState(() {
          _isAdLoaded = true;
        });
      },
      onAdFailedToLoad: (Ad ad, LoadAdError error) {
        ad.dispose();
        print('Ad failed to load: $error');
        setState(() {
          _isAdLoaded = false;
          _banner = null;
        });
      },
      onAdOpened: (Ad ad) => print('Ad opened.'),
      onAdClosed: (Ad ad) => print('Ad closed.'),
    ),
  );
  // 调用加载
  _banner!.load();
}

// 渲染逻辑修改为判断_isAdLoaded状态
@override
Widget build(BuildContext context) {
  return Column(
    children: [
      // 其他页面组件
      if(_isAdLoaded && _banner != null)
        Container(
          height: 50,
          child: AdWidget(ad: _banner!),
        )
      else
        const SizedBox(height: 50),
    ],
  );
}

@override
void dispose() {
  // 页面销毁时释放广告资源
  _banner?.dispose();
  super.dispose();
}

3. 验证测试环境

如果完成上述配置后仍有错误,检查Android 11测试设备的Google Play服务是否更新到最新版本,旧版Play服务对新版广告SDK的兼容存在问题,会偶发内部错误。


内容的提问来源于stack exchange,提问作者1ManStartup

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:15:02