Jetpack Compose点击Composable按钮触发AdMob插屏广告仅首次生效问题
插屏广告仅首次点击可展示后续加载失败的解决办法
AdMob插屏广告属于一次性消费资源,原有实例在展示完成、展示失败后就会失效,当前实现缺少广告生命周期监听、加载时机不合理,是导致后续点击无法加载的核心原因,可按以下方式调整:
- 调整广告加载时机:不要在按钮点击时才触发加载操作,建议在页面初始化时就启动首次预加载,广告消耗后立刻触发下一次预加载,避免点击时才异步加载导致的等待、以及短时间高频请求被AdMob限流。
- 新增广告全生命周期回调:在广告加载成功后为插屏实例配置
FullScreenContentCallback,监听广告的关闭、展示失败等事件,在事件触发时清空已失效的广告实例并触发下一次加载,修改后的loadInterstitial方法参考如下:
fun loadInterstitial(context: Context) { // 加载前先判断是否已有可用实例,避免重复请求 if (mInterstitialAd != null) return InterstitialAd.load( context, context.getString(R.string.ad_id_interstitial), AdRequest.Builder().build(), object : InterstitialAdLoadCallback() { override fun onAdFailedToLoad(adError: LoadAdError) { mInterstitialAd = null Log.d("MainActivity", "广告加载失败:${adError.message},错误码:${adError.code}") // 加载失败可做延迟重试,避免短时间重复请求被限流 Handler(Looper.getMainLooper()).postDelayed({ loadInterstitial(context) }, 5000) } override fun onAdLoaded(interstitialAd: InterstitialAd) { mInterstitialAd = interstitialAd // 配置广告展示生命周期回调 mInterstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() { override fun onAdDismissedFullScreenContent() { // 用户关闭广告,清空失效实例,预加载下一次广告 mInterstitialAd = null loadInterstitial(context) } override fun onAdFailedToShowFullScreenContent(adError: AdError) { // 广告展示失败,清空实例重新加载 mInterstitialAd = null loadInterstitial(context) } override fun onAdShowedFullScreenContent() { // 广告已开始展示,原有实例已不可复用,提前置空 mInterstitialAd = null } } Log.d("MainActivity", "广告加载完成") } } ) }
- 优化按钮点击逻辑:点击时优先判断是否有已加载完成的广告实例,有则直接展示,没有则提示用户并触发加载,不要在点击时强制调用加载方法:
Button(onClick = { mInterstitialAd?.run { show(context as Activity) } ?: run { Toast.makeText(context, "广告暂未准备完成,请稍后重试", Toast.LENGTH_SHORT).show() loadInterstitial(context) } }) { Text("点击展示广告") }
- 合理存储广告实例:如果在Compose场景下使用,建议将广告实例、加载逻辑放到ViewModel中持有,避免Composable重组导致实例丢失、加载逻辑被重复触发。
- 排查错误码:如果仍有加载失败的情况,可以查看
onAdFailedToLoad中打印的错误码定位具体问题,常见错误如3代表当前无广告填充,2代表网络问题,0代表内部请求错误。
内容的提问来源于stack exchange,提问作者Raw Hasan
相关产品推荐
相关产品推荐

