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

Jetpack Compose中InterstitialAd加载异常及TransactionTooLargeException排查

问题排查与解决方案

一、无限加载日志问题排查

1. 检查广告加载回调的循环调用逻辑

大概率是AdsHelper.kt中onLoadInterstitialAd的回调里重复触发了加载操作,导致无限循环:

// 错误示例:加载成功/失败后无限制重复调用加载
fun onLoadInterstitialAd(forceReload: Boolean) {
    if (interstitialAd == null || forceReload) {
        InterstitialAd.load(context, adUnitId, adRequest, object : AdLoadCallback() {
            override fun onAdLoaded(ad: InterstitialAd) {
                interstitialAd = ad
                onLoadInterstitialAd(true) // 此处会触发无限循环加载
            }
            override fun onAdFailedToLoad(error: LoadAdError) {
                interstitialAd = null
                onLoadInterstitialAd(true) // 错误的重试逻辑,无间隔重复加载
            }
        })
    }
}

修复方案:
加载成功后停止重复调用,失败后添加延迟重试,避免无限循环:

fun onLoadInterstitialAd(forceReload: Boolean) {
    if (interstitialAd == null || forceReload) {
        InterstitialAd.load(context, adUnitId, adRequest, object : AdLoadCallback() {
            override fun onAdLoaded(ad: InterstitialAd) {
                interstitialAd = ad
                // 加载成功后无需重复调用
            }
            override fun onAdFailedToLoad(error: LoadAdError) {
                interstitialAd = null
                // 5秒后重试,避免高频触发
                Handler(Looper.getMainLooper()).postDelayed({
                    onLoadInterstitialAd(true)
                }, 5000)
            }
        })
    }
}

2. 校验Compose中触发加载的逻辑

非HOME页面加载的判断可能因重组逻辑错误,导致重复触发加载:

// 错误示例:使用Unit作为key,每次UI重组都会执行
LaunchedEffect(Unit) {
    if (currentPage != HOME) {
        adsHelper?.onLoadInterstitialAd(true)
    }
}

修复方案:
以页面状态作为LaunchedEffect的key,仅在页面切换时触发加载:

LaunchedEffect(currentPage) {
    if (currentPage != HOME) {
        adsHelper?.onLoadInterstitialAd(false) // 非强制加载,避免重复请求
    }
}

二、TransactionTooLargeException与卡顿问题排查

1. 定位过大的状态传递

该异常是因为Activity的onSaveInstanceState中保存的数据超过1MB限制,检查以下点:

  • 查看MainActivity.kt的onSaveInstanceState,是否保存了整个Data对象(可能包含大量数据):
// 错误示例:保存完整大对象
override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putParcelable("app_data", data)
}

修复方案:仅保存必要的状态字段,而非整个对象:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putBoolean("interstitial_showing", data.interstitial)
}

2. 优化广告展示时的主线程操作

卡顿大概率是广告展示前在主线程执行了耗时操作,导致主线程阻塞:

// 错误示例:展示前执行耗时操作
fun showInterstitialAd() {
    heavyDataProcessing() // 耗时操作
    interstitialAd?.show(activity)
}

修复方案:将耗时操作移至后台线程,主线程仅执行广告展示:

fun showInterstitialAd() {
    CoroutineScope(Dispatchers.IO).launch {
        heavyDataProcessing()
        withContext(Dispatchers.Main) {
            interstitialAd?.show(activity)
        }
    }
}

3. 减少不必要的UI重组

检查data.interstitial=true时是否触发了大量UI组件重组:

  • 确保使用remember、derivedStateOf缓存计算结果,避免无关状态更新引发重组;
  • 广告展示状态仅控制广告组件的显示/隐藏,不联动其他无关UI的刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:37:08