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

如何在Compose Navigation中通过Koin注入实现共享ViewModel?

在Compose Navigation中使用Koin实现共享ViewModel的解决方案

你的代码中两个页面会创建BLEIoTViewModel新实例的核心原因是未明确指定共享的导航作用域,当前的sharedViewModel函数逻辑存在疏漏,导致无法复用同一ViewModel实例。以下是修正方案:

问题根源

你当前的NavHost没有给根导航图命名,导致destination.parent?.route可能返回null,此时函数会直接调用koinViewModel()——这个方法默认以当前页面的NavBackStackEntry作为ViewModelStoreOwner,每个页面自然会生成新的ViewModel实例。

修正步骤

1. 给根导航图指定命名路由

修改NavHost,为根导航图添加明确的route参数,让所有子页面归属同一作用域:

@Composable
fun NavigationSystem() {
    val navController = rememberNavController()

    NavHost(
        navController = navController,
        startDestination = "scan",
        route = "root_nav_graph" // 新增根导航图路由
    ) {
        composable("scan") {
            val viewModel: BLEIoTViewModel = it.sharedViewModel(navController)
            // ... 原有代码
        }
        composable("config") {
            val viewModel: BLEIoTViewModel = it.sharedViewModel(navController)
            // ... 原有代码
        }
    }
}

2. 修正sharedViewModel扩展函数逻辑

确保始终获取根导航图的BackStackEntry作为共享作用域,避免依赖可能为空的父路由:

@Composable
inline fun <reified T : ViewModel> NavBackStackEntry.sharedViewModel(
    navController: NavHostController,
    rootNavRoute: String = "root_nav_graph" // 与根导航图路由对应
): T {
    // 记住根导航图的BackStackEntry,确保跨页面复用同一实例
    val rootBackStackEntry = remember(rootNavRoute) {
        navController.getBackStackEntry(rootNavRoute)
    }
    // 基于根BackStackEntry获取ViewModel,实现共享
    return koinViewModel(viewModelStoreOwner = rootBackStackEntry)
}

3. 确认Koin模块的ViewModel声明正确

在你的Koin模块中,确保ViewModel的声明符合Koin的规范:

val bleModule = module {
    // 如果ViewModel有依赖(如Repository),通过get()注入
    viewModel { BLEIoTViewModel(get()) }
    // 无依赖则直接写:viewModel { BLEIoTViewModel() }
}

原理说明

当指定根导航图的路由后,两个页面都会获取同一个根BackStackEntry作为ViewModelStoreOwner,Koin会基于这个全局作用域创建并复用ViewModel实例,从而实现跨页面的数据共享。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 05:40:32