Flutter中Admob插屏广告显示失败:视图控制器未被呈现
Flutter Admob插屏广告调用show()失败,错误code17:the provided view controller is not being presented.
错误原因
这个错误是iOS平台专属问题,本质是Admob展示插屏广告时,无法获取到当前处于活跃状态的ViewController。常见触发场景:
- 调用
show()时,当前页面已经被弹出(pop) - 在页面未完全初始化完成时调用
show()(比如initState阶段直接调用) - 广告实例持有了已失效的ViewController引用
解决方法
针对上述场景,调整代码逻辑,确保广告展示时机和实例生命周期正确:
- 调用前检查页面状态:确保当前Widget处于
mounted状态,避免在页面已销毁时调用广告展示 - 延迟展示时机:通过
WidgetsBinding.instance.addPostFrameCallback确保页面渲染完成后再调用show() - 正确管理广告生命周期:广告展示完成或失败后,立即销毁实例并置空,避免重复使用失效实例
修正后的代码示例
void displayAd() async { // 先判断当前页面是否还活跃 if (!mounted) return; if (interstitialAd != null) { interstitialAd!.fullScreenContentCallback = FullScreenContentCallback( onAdDismissedFullScreenContent: (ad) { ad.dispose(); // 关闭后销毁广告实例 interstitialAd = null; convert(); }, onAdFailedToShowFullScreenContent: (ad, adError) { print(adError); ad.dispose(); // 展示失败也要销毁实例 interstitialAd = null; }, ); // 延迟到页面渲染完成后展示,确保ViewController状态正常 WidgetsBinding.instance.addPostFrameCallback((_) { interstitialAd!.show(); }); } }
额外注意事项
- 插屏广告实例只能使用一次,每次展示后必须销毁并重新加载新的广告
- 不要在
initState方法中直接调用show(),此时页面ViewController尚未完全就绪 - 如果是在异步操作(比如网络请求)完成后调用展示,要先确认当前页面仍在栈顶且未被销毁
内容的提问来源于stack exchange,提问作者shakti goyal
相关产品推荐
相关产品推荐

