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

Jetpack Compose中从Activity带参数跳转至Compose页面的实现方法

问题

我在Jetpack项目中集成了激励插屏广告(Rewarded Interstitial Ad),用RewardedShowActivity展示广告。已经实现从Compose页面带参数跳转到这个Activity,但现在需要在用户完成广告后,通过OnUserEarnedRewardListener从Activity带参数导航到Compose的FinalShow页面,卡在这里了。

以下是我的相关代码:

Screens密封类

sealed class Screens(val route: String) {
    object SMasks : Screens("s_masks")
    object BMasks : Screens("b_masks")
    object FinalShow : Screens("final_show")
    object ProgressBar : Screens("progress_bar")
    object RewardedShow : Screens("rewarded_show")
}
@SuppressLint("UnrememberedMutableState")
@Composable
fun MyNavGraph(navController: NavHostController) {
    val actions = remember(navController) { MainActions(navController) }

    NavHost(
        navController = navController,
        startDestination = BottomNavItems.SMasks.route
    ) {
        composable(BottomNavItems.SMasks.route) {
            SMaskScreen(actions)
        }

        composable(Screens.BMasks.route) {
            BMasksScreen(navController, actions)
        }
   
        composable("${Screens.FinalShow.route}/{maskArg}") { backStackEntry ->
            val maskArg = backStackEntry.arguments?.getString("maskArg")
            maskArg?.let {
                FinalShowScreen(maskArg = it, navController)
            }
        }
    }
}

class MainActions(navController: NavController) {
    val gotoFinalShow: (String) -> Unit = { maskArg ->
        navController.navigate("${Screens.FinalShow.route}/$maskArg") {
            launchSingleTop = true
            restoreState = true
        }
    }
}

Compose跳转至Activity的代码

onItemClick = {
    val maskArg = "mask1"
    goToActivity(maskArg = maskArg, context = context)
}

fun goToActivity(context: Context, maskArg: String) {
    val intent = Intent(context, RewardedShowActivity::class.java)
    intent.putExtra("maskArg", maskArg)
    context.startActivity(intent)
}

RewardedShowActivity代码

class RewardedShowActivity : ComponentActivity(), OnUserEarnedRewardListener {
    val loading = mutableStateOf(true)

    private companion object {
        const val TAG = "TAG"
    }
    private var mRewardedInterstitialAd: RewardedInterstitialAd? = null

    @SuppressLint("UnrememberedMutableState")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val maskArg = intent.extras!!.getString("maskArg")

        setContent {
            MyAppTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    CircleIndeterminateProgressBar(isDisplayed = loading)
                }
            }
        }
    }

    override fun onUserEarnedReward(p0: RewardItem) {
        // 这里需要实现跳转逻辑
    }
}

解决方案

方法一:通过Activity Result API返回结果(推荐,符合Android架构规范)

这种方式让Compose页面负责导航逻辑,Activity只专注于广告展示和结果返回,耦合度更低。

1. 在Compose页面注册Activity Result Contract

在发起跳转的Compose页面(比如SMaskScreen)中,注册结果回调:

@Composable
fun SMaskScreen(actions: MainActions) {
    val context = LocalContext.current
    // 注册Activity结果回调
    val getRewardResult = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult()
    ) { result ->
        if (result.resultCode == RESULT_OK) {
            // 获取返回的mask参数
            val maskArg = result.data?.getStringExtra("maskArg")
            maskArg?.let {
                // 调用已有的导航方法跳转到FinalShow
                actions.gotoFinalShow(it)
            }
        }
    }

    // 修改点击事件,用注册的回调启动Activity
    val onItemClick = {
        val maskArg = "mask1"
        val intent = Intent(context, RewardedShowActivity::class.java)
        intent.putExtra("maskArg", maskArg)
        getRewardResult.launch(intent)
    }

    // 页面其他内容...
}

2. 修改RewardedShowActivity的onUserEarnedReward方法

用户获得奖励后,设置返回结果并关闭当前Activity:

override fun onUserEarnedReward(p0: RewardItem) {
    // 获取之前传递的mask参数
    val maskArg = intent.extras?.getString("maskArg")
    // 创建返回Intent并携带参数
    val resultIntent = Intent()
    maskArg?.let { resultIntent.putExtra("maskArg", it) }
    // 设置成功结果码
    setResult(RESULT_OK, resultIntent)
    // 关闭当前Activity
    finish()
}

方法二:直接在Activity中获取NavController导航(适合单Activity架构)

如果你的项目是单Activity架构(所有Compose页面都在同一个Activity的NavHost中),可以直接获取NavController执行导航:

修改RewardedShowActivity的onUserEarnedReward方法

override fun onUserEarnedReward(p0: RewardItem) {
    val maskArg = intent.extras?.getString("maskArg") ?: return
    // 获取NavController,替换成你的NavHost布局ID
    val navController = findNavController(R.id.nav_host_fragment)
    // 导航到FinalShow页面
    navController.navigate("${Screens.FinalShow.route}/$maskArg") {
        launchSingleTop = true
        restoreState = true
    }
    // 关闭当前Activity
    finish()
}

注意:这种方法要求RewardedShowActivity和承载NavHost的是同一个Activity,否则无法正确获取NavController实例。多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.20 17:42:14