Hilt 2.52中AssistedInject ViewModel使用报错排查求助
问题:Hilt 2.52中AssistedInject ViewModel在Composable中崩溃
报错信息:
java.lang.IllegalStateException: Found @HiltViewModel-annotated class UserProfileViewModel using @AssistedInject but no creation callback was provided in CreationExtras.
ViewModel定义
@HiltViewModel(assistedFactory = UserProfileViewModel.Factory::class) class UserProfileViewModel @AssistedInject constructor( private val sharedPreferences: EngClubSharedPreferences, private val authRepository: AuthRepository, private val resourceRepo: FileResourceRepository, @ApplicationContext private val context: Context, @Assisted private val user: User? ): ViewModel() { @AssistedFactory interface Factory { fun create(user: User?): UserProfileViewModel } }
Composable调用代码
@Composable fun UserProfileScreen( modifier: Modifier = Modifier, isSessionUser: Boolean = true, user: User? = sessionUser, onNavigateUp: () -> Unit, onLogoutOrDeletedAccount: () -> Unit ) { val navController = rememberNavController() val viewModel: UserProfileViewModel = hiltViewModel( creationCallback = { factory: UserProfileViewModel.Factory -> factory.create(user) } ) NavHost( modifier = modifier.fillMaxSize(), navController = navController, startDestination = ProfileViewingScreen.route ) { composable(route = ProfileViewingScreen.route) { UserProfileViewingScreen( isSessionUser = isSessionUser, viewModel = viewModel, onNavigateUp = onNavigateUp, navigateToEditScreen = { navController.navigate(EditProfileScreen.route) }, onLogoutOrDeletedAccount = onLogoutOrDeletedAccount ) } } }
用户疑问:该错误的原因是什么?代码库其他地方类似配置能正常运行,是不是遗漏了什么?
其他正常运行的代码示例
composable( route = "${MessageClubRoute.path}?groupID={groupID}", arguments = listOf(navArgument("groupID") { type = NavType.StringType defaultValue = "" } ) ) { val groupID = it.arguments?.getString("groupID") val messagingClubViewModel = hiltViewModel<MessageClubViewModel,MessageClubViewModel.Factory>( creationCallback = { factory -> factory.create(groupID = "$groupID") } ) MessageClubRoomNavigation(viewModel = messagingClubViewModel) }
解决方案
错误原因:你在NavHost外部调用hiltViewModel创建ViewModel,而Hilt的hiltViewModel函数依赖Navigation的NavBackStackEntry上下文才能正确传递包含creationCallback的CreationExtras。
对比正常代码就能看到差异:正常代码是在composable的lambda内部创建ViewModel,这里会自动获取当前路由对应的NavBackStackEntry,能把creationCallback正确注入到Hilt的创建流程中;而你的用户资料页面代码在NavHost外初始化ViewModel,此时没有对应的导航栈上下文,导致Hilt找不到你提供的creationCallback,从而抛出异常。
修正方法:将ViewModel的创建逻辑移到composable的lambda内部,也就是UserProfileViewingScreen所在的代码块里:
@Composable fun UserProfileScreen( modifier: Modifier = Modifier, isSessionUser: Boolean = true, user: User? = sessionUser, onNavigateUp: () -> Unit, onLogoutOrDeletedAccount: () -> Unit ) { val navController = rememberNavController() NavHost( modifier = modifier.fillMaxSize(), navController = navController, startDestination = ProfileViewingScreen.route ) { composable(route = ProfileViewingScreen.route) { // 移到此处创建ViewModel val viewModel: UserProfileViewModel = hiltViewModel( creationCallback = { factory: UserProfileViewModel.Factory -> factory.create(user) } ) UserProfileViewingScreen( isSessionUser = isSessionUser, viewModel = viewModel, onNavigateUp = onNavigateUp, navigateToEditScreen = { navController.navigate(EditProfileScreen.route) }, onLogoutOrDeletedAccount = onLogoutOrDeletedAccount ) } } }
这样hiltViewModel就能获取当前路由的NavBackStackEntry上下文,正确传递creationCallback给Hilt,解决崩溃问题。
内容的提问来源于stack exchange,提问作者Nnaoma miracle
相关产品推荐
相关产品推荐

