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

如何在Jetpack Compose中通过Dagger/Hilt注入共享全局ViewModel实例?

在Jetpack Compose中通过Hilt共享全局ViewModel实例

你的问题核心在于:hiltViewModel()默认会将ViewModel与当前的NavBackStackEntry绑定,每个导航屏幕都会创建独立的ViewModel实例,导致无法共享状态。要实现全局共享,需要让ViewModel与Activity的生命周期绑定,以下是两种可行方案:

方案1:指定ViewModelStoreOwner为Activity

hiltViewModel()允许传入自定义的ViewModelStoreOwner,只需指定为当前Activity,就能拿到与Activity同生命周期的全局实例:

首先确保你的ViewModel添加了@HiltViewModel注解(Hilt注入的必要条件):

@HiltViewModel
class MainNavigationViewModel @Inject constructor(
    // 这里注入你的依赖,比如Repository等
) : ViewModel() {
    // 你的状态定义,比如StateFlow
    val state = MutableStateFlow(NavigationMeasurements())
}

然后在屏幕Composable中,通过LocalContext获取Activity实例并传入hiltViewModel():

@Composable
fun ScreenA(
    navigationViewModel: MainNavigationViewModel = hiltViewModel(
        viewModelStoreOwner = LocalContext.current as MainActivity
    )
) {
    val uiState by navigationViewModel.state.collectAsStateWithLifecycle()
    // 你的界面逻辑
}

注意:如果你的Activity继承自AppCompatActivity,也可以强转为AppCompatActivity,只要确保是当前承载Compose的Activity实例即可。

方案2:使用CompositionLocal全局提供ViewModel

这种方式更简洁,适合全局频繁使用的ViewModel,避免重复传递参数:

  1. 先定义一个CompositionLocal:
val LocalMainNavigationViewModel = compositionLocalOf<MainNavigationViewModel> {
    error("MainNavigationViewModel未在CompositionLocal中提供")
}
  1. 在Activity的Composable中提供这个ViewModel:
@AndroidEntryPoint
class MainActivity : BaseActivity() {

    override val viewModel: MainNavigationViewModel by viewModels()

    override val screen: @Composable () -> Unit = {
        CompositionLocalProvider(LocalMainNavigationViewModel provides viewModel) {
            MainNavigation()
        }
    }
}
  1. 在任意子Composable中直接获取全局实例:
@Composable
fun ScreenA(
    navigationViewModel: MainNavigationViewModel = LocalMainNavigationViewModel.current
) {
    val uiState by navigationViewModel.state.collectAsStateWithLifecycle()
    // 你的界面逻辑
}

关键注意事项

  • 必须给ViewModel添加@HiltViewModel注解,否则Hilt无法完成依赖注入并管理实例。
  • 避免使用普通的viewModel()函数,它不支持Hilt注入,且默认作用域也是当前Composable的ViewModelStoreOwner。
  • 两种方案都能保证ViewModel与Activity同生命周期,只要Activity不销毁,状态就会持续共享,所有订阅状态的Composable都会自动重组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 15:57:44