You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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) }后,该代码块从未执行

问题根源

  1. 参数类型要求变更:Admob 21.x版本后,AppOpenAd.show()方法要求传入非空的Activity实例,而原代码中currentActivity为可空类型,直接传入会触发类型不匹配错误。
  2. 生命周期执行顺序问题: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)
}

修复后流程说明

  1. 应用启动或从后台回到前台时,onActivityResumed会先赋值currentActivity,再调用showAdIfAvailable()
  2. 此时currentActivity已非空,满足AppOpenAd.show()的参数要求,广告可正常展示
  3. 无论广告展示成功、失败还是被关闭,都会重置状态并自动请求下一个广告

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 01:40:24