AdMob警告布局易引发误触:意外启动插屏广告(Jetpack Compose)
解决AdMob“Layout Encourages Accidental Clicks - Unexpected Launch Interstitials”警告
问题背景
使用Kotlin+Jetpack Compose开发的应用收到AdMob警告,原因是用户返回页面后广告才加载完成并弹出,触发了AdMob的误触检测机制。现有逻辑中,返回操作与广告加载/展示不同步,广告加载速度慢于页面切换,导致广告在用户回到上一页后意外弹出。
核心问题分析
- 广告加载时机滞后:当前在用户点击返回时才开始加载广告,若广告加载耗时较长,会出现页面已经返回、广告才弹出的情况,符合AdMob禁止的“意外插屏广告”场景。
- 页面返回与广告展示不同步:返回操作(
navController.popBackStack())直接执行,未等待广告展示完成或确认广告是否已加载,导致广告状态与页面状态脱节。
解决方案
1. 提前预加载广告,避免返回时才启动加载
在应用启动或进入目标页面时就预加载插屏广告,确保用户点击返回时广告已准备就绪。修改MainActivity的初始化逻辑:
class MainActivity : ComponentActivity() { private var mInterstitialAd: InterstitialAd? = null private var adId: String = "some_id_123456" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 启动时立即预加载广告 loadInterstitialAd { initialAdStatus -> runOnUiThread { setContent { val currentTheme = isSystemInDarkTheme() var darkTheme by remember { mutableStateOf(currentTheme) } var adStatusState by remember { mutableStateOf(initialAdStatus) } MyAppTheme(darkTheme = darkTheme) { Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { MY_APP( darkTheme = darkTheme, onThemeUpdated = { darkTheme = !darkTheme }, onBackButtonClicked = { adDismissedCallback -> if (adStatusState) { // 展示已预加载的广告 showInterstitialAd { adStatusState = false // 广告关闭后立即预加载下一个 loadInterstitialAd { adStatusState = it } adDismissedCallback() } } else { // 无可用广告,直接执行返回回调 adDismissedCallback() // 同时预加载下一个广告 loadInterstitialAd { adStatusState = it } } } ) } } } } } } private fun loadInterstitialAd(adStatus: (Boolean) -> Unit) { val adRequest = AdRequest.Builder().build() InterstitialAd.load( this, adId, adRequest, object : InterstitialAdLoadCallback() { override fun onAdFailedToLoad(adError: LoadAdError) { mInterstitialAd = null adStatus(false) } override fun onAdLoaded(interstitialAd: InterstitialAd) { mInterstitialAd = interstitialAd adStatus(true) } } ) } // 修改showInterstitialAd,添加广告关闭回调 private fun showInterstitialAd(onAdDismissed: () -> Unit) { mInterstitialAd?.let { ad -> ad.fullScreenContentCallback = object : FullScreenContentCallback() { override fun onAdShowedFullScreenContent() { mInterstitialAd = null } override fun onAdDismissedFullScreenContent() { onAdDismissed() } // 处理广告展示失败的情况,确保回调执行 override fun onAdFailedToShowFullScreenContent(adError: AdError) { mInterstitialAd = null onAdDismissed() } } ad.show(this) } ?: run { Toast.makeText(this, "No ad shows", Toast.LENGTH_SHORT).show() onAdDismissed() } } }
2. 同步页面返回与广告展示逻辑
确保只有在广告展示完成(或确认无可用广告)后,才执行页面返回操作,避免广告在页面切换后弹出。修改返回逻辑:
val onMoveBack: () -> Unit = { // 通过回调控制页面返回时机 onBackButtonClicked { navController.popBackStack() } }
3. 遵守AdMob插屏广告规范
- 广告仅在用户主动触发的操作(如明确点击返回按钮)后立即展示,绝不延迟弹出。
- 广告展示后,确保用户可正常关闭,关闭后回到预期页面。
- 避免在页面加载、切换等用户未主动触发的场景下弹出广告。
内容的提问来源于stack exchange,提问作者vinhDev3006
相关产品推荐
相关产品推荐

