Flutter集成firebase_admob时插屏广告仅能弹出两次、第三次无法展示问题排查
插屏广告第三次无法展示的逻辑缺陷定位
执行时序匹配(完全对应「前两次正常、第三次失效」的现象)
逐行拆解代码的实际运行流程:
- 页面初始化时,
initState方法创建了带完整事件监听的插屏广告实例A,执行load()触发广告加载,实例加载完成后触发MobileAdEvent.loaded事件,将_isInterstitialAdReady置为true - 累计满10次按钮点击后,判断条件满足,调用实例A的
show()弹出第一次广告;用户关闭广告后,触发实例A的closed回调:销毁旧实例A,将全局_interstitialAd指向类定义阶段创建的空监听实例B,同时调用B的load()触发加载 - 因为实例B没有绑定任何事件监听器,后续的加载完成、加载失败、广告关闭等事件全部无法被捕获,
_isInterstitialAdReady的值会一直停留在之前的true状态(没有任何代码会修改它) - 再次累计满10次按钮点击时,判断条件依然满足,直接调用实例B的
show()弹出第二次广告——此时实例B已经完成加载,哪怕没有监听器也能正常展示,所以第二次广告可以正常弹出 - 用户关闭第二次广告时,因为实例B没有任何监听逻辑,完全不会触发「销毁旧实例、创建新实例、重新加载」的流程;此时
_interstitialAd指向的实例B已经被广告SDK标记为已销毁的失效状态,但_isInterstitialAdReady依然保持true - 第三次累计满10次按钮点击时,判断条件满足,对已经失效的实例B执行
..load()..show()操作,因为实例本身已失效,既无法成功展示广告,也不会触发任何状态更新的回调,最终导致第三次广告永远无法弹出
具体逻辑缺陷
- 全局复用的空监听广告实例设计错误
类定义阶段创建的_createInterstitialAd实例没有绑定任何事件监听器,一旦把原有的带完整监听的有效实例替换成这个空监听实例,后续所有和广告状态相关的事件都会丢失,整个广告状态机直接失效。 - 广告就绪状态的更新逻辑缺失
代码仅在loaded/failedToLoad事件中更新_isInterstitialAdReady,既没有在广告被展示、被关闭时把标记重置为false,也没有在实例被销毁时同步状态,导致标记值和广告真实的就绪状态长期脱节。 - 广告触发时的链式调用逻辑错误
满足展示条件时直接链式执行..load()..show(),插屏广告的加载是异步流程,未加载完成的广告直接调用show不会弹出;且已经加载完成的广告重复调用load,会打断当前实例的可用状态,进一步加剧状态错乱。
修复参考方向
- 移除全局复用的空监听
_createInterstitialAd实例,每次收到广告关闭、销毁的回调时,重新创建一个绑定完整事件监听器的新插屏广告实例,再触发加载 - 补充事件状态同步:在广告被成功展示、被关闭的回调中,立即将
_isInterstitialAdReady置为false,明确标记当前实例已使用、不可再次展示 - 调整触发逻辑:满足点击次数条件时,仅在
_isInterstitialAdReady为true时调用show(),不要在展示前重复调用已就绪实例的load()方法,展示完成后重置点击计数器 - 补充加载失败的兜底逻辑:当收到
failedToLoad事件时,按合理间隔重新触发广告加载,避免实例失效后没有可展示的广告
内容的提问来源于stack exchange,提问作者Dsema
相关产品推荐
相关产品推荐

