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

如何在Jetpack Compose中展示MainActivity加载的RewardedInterstitial广告?

问题原因及解决方案

问题根源

你在Composable中直接通过MainActivity.rewardedInterstitialAd访问广告实例是错误的——rewardedInterstitialAd是MainActivity的非静态成员变量,每个Activity实例都有自己的副本,而你通过类名访问相当于试图读取一个不存在的静态变量,自然会得到null。

正确解决方案

推荐使用ViewModel来管理广告实例,这是Jetpack生态中跨UI组件共享状态的标准方式,也能避免Activity实例引用导致的内存泄漏问题。

步骤1:创建广告管理ViewModel

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.RewardedInterstitialAd
import com.google.android.gms.ads.RewardedInterstitialAdLoadCallback

class AdViewModel(application: Application) : AndroidViewModel(application) {
    val rewardedInterstitialAd = MutableLiveData<RewardedInterstitialAd?>()
    private val TAG = "AdViewModel"

    fun loadRewardedInterstitialAd() {
        RewardedInterstitialAd.load(
            getApplication(),
            "ca-app-pub-3940256099942544/5354046379",
            AdRequest.Builder().build(),
            object : RewardedInterstitialAdLoadCallback() {
                override fun onAdLoaded(ad: RewardedInterstitialAd) {
                    rewardedInterstitialAd.value = ad
                }

                override fun onAdFailedToLoad(adError: LoadAdError) {
                    rewardedInterstitialAd.value = null
                }
            }
        )
    }
}

步骤2:在MainActivity中初始化ViewModel并加载广告

class MainActivity : ComponentActivity() {
    private lateinit var adViewModel: AdViewModel
    private val TAG = "MainActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        adViewModel = ViewModelProvider(this)[AdViewModel::class.java]

        setContent {
            MyBeautyAppInJetpackComposeTheme {
                MyNavGraph()
                MobileAds.initialize(this) {
                    adViewModel.loadRewardedInterstitialAd()
                }
            }
        }
    }
}

步骤3:在Composable中使用ViewModel获取广告实例

@Composable
fun RewardedShowCompose(actions: MainActions, maskArg: String) {
    val context = LocalContext.current
    val adViewModel = viewModel<AdViewModel>()
    // 用remember保存状态,避免重组时重置
    val loading = remember { mutableStateOf(true) }

    Surface(modifier = Modifier.fillMaxSize()) {
        adViewModel.rewardedInterstitialAd.observeAsState().value?.let { ad ->
            ad.show(context as Activity) {
                actions.gotoFinalShow.invoke(maskArg)
                // 广告展示后清空实例,避免重复展示
                adViewModel.rewardedInterstitialAd.value = null
                // 可在此触发下一次广告加载,方便后续使用
                adViewModel.loadRewardedInterstitialAd()
            }
        }
    }
}

备选方案(不推荐,仅作参考)

如果暂时不想引入ViewModel,也可以通过LocalContext获取当前MainActivity实例,再访问其成员变量,但要注意类型转换的安全性:

修改MainActivity的变量为可访问

class MainActivity : ComponentActivity(){
    var rewardedInterstitialAd: RewardedInterstitialAd? = null
    // ... 其他代码不变
}

在Composable中获取Activity实例

@Composable
fun RewardedShowCompose(actions: MainActions, maskArg: String) {
    val context = LocalContext.current
    val loading = remember { mutableStateOf(true) }
    val mainActivity = context as? MainActivity

    Surface(modifier = Modifier.fillMaxSize()) {
        mainActivity?.rewardedInterstitialAd?.let { ad ->
            ad.show(mainActivity) {
                actions.gotoFinalShow.invoke(maskArg)
                mainActivity.rewardedInterstitialAd = null
                mainActivity.loadAd()
            }
        }
    }
}

注意:这种方式直接持有Activity引用,容易导致内存泄漏,不推荐在生产环境使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:15:31