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") }
NavGraph代码
@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
相关产品推荐
相关产品推荐

