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
相关产品推荐
相关产品推荐

