Android Admob 21.4.0版本App Open Ads无法显示问题求助
Admob 21.4.0版本下App Open Ads显示异常的解决方案
问题背景
将Admob从20.6.0升级到21.4.0后,原正常运行的App Open Ads出现异常:
- 在
showAdIfAvailable()方法中,appOpenAd?.show(currentActivity)代码行提示Type mismatch. Required: Activity Found: Activity? - 按提示改用
currentActivity?.let { appOpenAd?.show(it) }后,该代码块从未执行
问题根源
- 参数类型要求变更:Admob 21.x版本后,
AppOpenAd.show()方法要求传入非空的Activity实例,而原代码中currentActivity为可空类型,直接传入会触发类型不匹配错误。 - 生命周期执行顺序问题:
ProcessLifecycleOwner的onStart回调会先于Activity的onActivityStarted触发,此时currentActivity尚未被赋值,导致currentActivity?.let代码块因空值跳过执行。
具体修复步骤
1. 调整广告展示时机
将showAdIfAvailable()的调用从ProcessLifecycleOwner的onStart回调,移到Activity的onActivityResumed回调中,确保currentActivity已被正确赋值:
// 修改AppOpenManager中的onStart方法,移除showAdIfAvailable调用 override fun onStart(owner: LifecycleOwner) { super.onStart(owner) // showAdIfAvailable() 移至onActivityResumed执行 println("onStart") } // 修改onActivityResumed方法,添加广告展示逻辑 override fun onActivityResumed(activity: Activity) { println("⚠️ onActivityResumed") currentActivity = activity // 仅当应用处于前台且无广告正在展示时,尝试展示广告 if (!isShowingAd && ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) { showAdIfAvailable() } }
2. 安全处理可空Activity与广告展示
在showAdIfAvailable()中,先校验currentActivity非空,再执行广告展示逻辑,同时完善错误状态重置:
private fun showAdIfAvailable() { // 增加currentActivity非空判断 if (!isShowingAd && isAdAvailable() && currentActivity != null) { println("Will show ad.") val fullScreenContentCallback = object: FullScreenContentCallback() { override fun onAdDismissedFullScreenContent() { this@AppOpenManager.appOpenAd = null isShowingAd = false fetchAd() } override fun onAdFailedToShowFullScreenContent(adError: AdError) { // 广告展示失败时也要重置状态,避免阻塞后续广告加载 this@AppOpenManager.appOpenAd = null isShowingAd = false println("Ad failed to show: $adError") fetchAd() } override fun onAdShowedFullScreenContent() { isShowingAd = true } } appOpenAd?.fullScreenContentCallback = fullScreenContentCallback // 使用let安全调用show方法 currentActivity?.let { safeActivity -> appOpenAd?.show(safeActivity) } } else { println("Can not show ad... FETCH ONE INSTEAD!") fetchAd() } }
3. 修复生命周期回调注册逻辑
原代码仅在API >= Q时注册Activity生命周期回调,导致低版本系统中currentActivity无法被赋值,直接移除版本判断:
init { // 移除API版本判断,确保所有版本都能注册生命周期回调 this.myApplication.registerActivityLifecycleCallbacks(this) ProcessLifecycleOwner.get().lifecycle.addObserver(this) }
修复后流程说明
- 应用启动或从后台回到前台时,
onActivityResumed会先赋值currentActivity,再调用showAdIfAvailable() - 此时
currentActivity已非空,满足AppOpenAd.show()的参数要求,广告可正常展示 - 无论广告展示成功、失败还是被关闭,都会重置状态并自动请求下一个广告
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

