Flutter中ImagePicker选媒体后显示插屏广告报错问题
问题解决:相册选择后显示插屏广告报错"The provided view controller is already presenting another view controller"
错误原因
调用pickVideo选择视频后,系统原生的相册选择器ViewController还未完全关闭(dismiss),就立刻触发插屏广告的show()方法。此时当前ViewController仍在present相册的VC,无法再叠加present广告的VC,导致报错。
解决方案
确保相册选择器完全关闭后,再显示广告,可通过以下两种方式实现:
方案1:使用WidgetsBinding的addPostFrameCallback
利用此回调确保当前UI帧绘制完成(此时相册VC已关闭)后再执行广告显示逻辑:
void pickFromGallery() async { ImagePicker imagePicker = ImagePicker(); XFile? pickedVideo = await imagePicker.pickVideo(source: ImageSource.gallery); if (pickedVideo != null) { // 等待当前帧结束后再初始化广告 WidgetsBinding.instance.addPostFrameCallback((_) { initialise(pickedVideo.path); }); } } void initialise(String path) async { if (interstitialAd != null) { interstitialAd!.fullScreenContentCallback = FullScreenContentCallback( onAdDismissedFullScreenContent: (ad) { // 广告关闭后再执行后续逻辑,比如显示视频内容 show(pickedVideo: File(path)); ad.dispose(); interstitialAd = null; // 按需重置广告实例 }, onAdFailedToShowFullScreenContent: (ad, adError) { print(adError); show(pickedVideo: File(path)); // 广告失败时直接显示内容 ad.dispose(); interstitialAd = null; }, ); await interstitialAd!.show(); } else { show(pickedVideo: File(path)); } }
方案2:添加短暂延迟
给系统足够时间关闭相册VC,再调用广告显示(延迟时间可根据实际情况调整):
void pickFromGallery() async { ImagePicker imagePicker = ImagePicker(); XFile? pickedVideo = await imagePicker.pickVideo(source: ImageSource.gallery); if (pickedVideo != null) { // 延迟100ms确保相册VC关闭 await Future.delayed(const Duration(milliseconds: 100)); initialise(pickedVideo.path); } }
额外注意事项
- 广告关闭后记得调用
ad.dispose()释放资源,并重置interstitialAd实例,避免后续重复使用导致异常。 - 广告显示失败时,要兜底执行原本的业务逻辑(比如直接显示选中的视频),避免阻塞用户流程。
内容的提问来源于stack exchange,提问作者shakti goyal
相关产品推荐
相关产品推荐

