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

如何在Compose Destination中跨Activity/进程销毁保留导航状态?

解决Compose Destinations跨Activity/进程销毁保存导航状态的问题

你的代码中,Activity销毁恢复后导航回到初始页面,核心原因是没有保存并恢复导航控制器的状态。要实现跨Activity正常销毁重建、甚至进程销毁后的导航状态恢复,需要结合内存状态保存和本地持久化存储两种方式,具体实现如下:

实现步骤与代码示例

class BaseActivity : AppCompatActivity() {
    // 定义本地存储的键名
    private val NAV_STATE_PREFS = "nav_state_prefs"
    private val NAV_STATE_KEY = "nav_controller_state"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 从本地存储读取之前保存的导航状态(应对进程销毁场景)
        val savedNavState = getSharedPreferences(NAV_STATE_PREFS, MODE_PRIVATE)
            .getBundle(NAV_STATE_KEY)

        setContent {
            MyTheme {
                val navController = rememberNavController()

                // 监听导航状态变化,实时保存到本地存储
                DisposableEffect(navController) {
                    val listener = NavController.OnDestinationChangedListener { _, _, _ ->
                        navController.saveState()?.let { state ->
                            getSharedPreferences(NAV_STATE_PREFS, MODE_PRIVATE)
                                .edit()
                                .putBundle(NAV_STATE_KEY, state)
                                .apply()
                        }
                    }
                    navController.addOnDestinationChangedListener(listener)
                    // 组件销毁时移除监听
                    onDispose {
                        navController.removeOnDestinationChangedListener(listener)
                    }
                }

                // 恢复导航状态:优先用本地存储的状态,其次用Activity的savedInstanceState
                val restoreState = savedNavState ?: savedInstanceState?.getBundle(NAV_STATE_KEY)
                restoreState?.let { navController.restoreState(it) }

                DestinationsNavHost(
                    navGraph = NavGraphs.root,
                    navController = navController,
                    // 若已恢复状态,则无需指定startRoute,避免覆盖导航栈;否则用默认初始页
                    startRoute = restoreState?.run { null } ?: FirstScreenDestination
                )
            }
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        // 保存状态到Activity的savedInstanceState(应对屏幕旋转等正常销毁重建场景)
        navController.saveState()?.let {
            outState.putBundle(NAV_STATE_KEY, it)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        // 可选:用户主动退出APP时清除本地状态,下次启动回到初始页
        if (isFinishing) {
            getSharedPreferences(NAV_STATE_PREFS, MODE_PRIVATE)
                .edit()
                .remove(NAV_STATE_KEY)
                .apply()
        }
    }
}

关键说明

  • 实时持久化:通过DisposableEffect监听导航变化,每次页面跳转都将当前导航栈状态保存到SharedPreferences,确保进程被系统回收后仍能读取到状态。
  • 状态恢复优先级:启动时优先读取本地存储的状态(应对进程销毁),其次读取Activity的savedInstanceState(应对正常销毁重建),恢复到导航控制器中。
  • 避免初始页覆盖:恢复状态后将startRoute设为null,防止默认初始页覆盖已恢复的导航栈。
  • 主动退出清除状态:在onDestroy中判断用户是否主动退出APP,若是则清除本地状态,保证下次启动从初始页开始。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 19:50:09