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

Jetpack Compose中NavHost启动时LoginViewModel实例创建失败

问题解决:Hilt ViewModel在Jetpack Compose NavHost中无法实例化

问题场景

直接将RegistrationFrame2()作为独立Composable组件运行时程序正常,但将其作为NavHost的起始目标时,抛出以下错误:

Process: com.example.application_digital, PID: 5298
java.lang.RuntimeException: Cannot create an instance of class 
com.example.application_digital.features.registration.presentation.
login.view_models.LoginViewModel

Caused by: java.lang.InstantiationException: 
 java.lang.Class<com.example.application_digital.features.
 registration.presentation.login.view_models.LoginViewModel> 
 has no zero argument constructor

报错原因

你的LoginViewModel使用@HiltViewModel注解,依赖Hilt完成依赖注入,构造函数包含多个参数而非无参构造。但在Composable中调用viewModel<LoginViewModel>()时,默认会使用ViewModelProvider的默认Factory,它要求ViewModel必须有无参构造函数。

直接运行RegistrationFrame2时能正常工作,是因为父组件(如测试用Activity)已配置Hilt,ViewModel实例化走了Hilt的注入逻辑;但在NavHost中,默认的ViewModel获取方式未关联Hilt的注入机制,导致无法实例化带参数的ViewModel。

解决步骤

1. 替换ViewModel获取方式

在RegistrationFrame2中,将所有使用viewModel()获取ViewModel的代码替换为Hilt提供的hiltViewModel()方法:

修改前:

val tabViewModel = viewModel<TabRowViewModel>()
val loginViewModel = viewModel<LoginViewModel>()
val signupViewModel = viewModel<SignupViewModel>()

修改后:

val tabViewModel = hiltViewModel<TabRowViewModel>()
val loginViewModel = hiltViewModel<LoginViewModel>()
val signupViewModel = hiltViewModel<SignupViewModel>()

2. 确保父组件已配置Hilt

  • 你的Application类必须添加@HiltAndroidApp注解:
@HiltAndroidApp
class MyApplication : Application() {
    // ...
}
  • 承载NavHost的Activity必须添加@AndroidEntryPoint注解:
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val navController = rememberNavController()
            RootNavigator(navController)
        }
    }
}

3. 验证其他ViewModel的注解

确保TabRowViewModel和SignupViewModel也添加了@HiltViewModel注解,并且构造函数使用@Inject注解,和LoginViewModel的写法保持一致。

修改后的RegistrationFrame2关键代码片段

@Composable
fun RegistrationFrame2() {
    val context = LocalContext.current
    val focusRequester = remember { FocusRequester() }
    // 使用hiltViewModel替代viewModel
    val tabViewModel = hiltViewModel<TabRowViewModel>()
    val loginViewModel = hiltViewModel<LoginViewModel>()
    val signupViewModel = hiltViewModel<SignupViewModel>()
    val initialText = tabViewModel.getRegistrationInitialText(context)
    val focusManager = LocalFocusManager.current

    // 后续代码保持不变...
}

内容的提问来源于stack exchange,提问作者zero.one

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 18:05:17