Android Hilt注入AuthApi到LoginViewModel时实例创建失败求助
问题:Hilt注入AuthApi到@HiltViewModel时无法实例化ViewModel
为带有@HiltViewModel注解的LoginViewModel构造函数注入AuthApi后,抛出错误:Cannot create an instance of class newjeans.bunnies.auth.viewmodel.LoginViewModel;移除构造函数中的private val authApi: AuthApi参数后,LoginViewModel可正常实例化。
已完成的配置与尝试:
- 已通过
NetworkModule提供AuthApi的单例实例 AuthActivity已添加@AndroidEntryPoint注解- 尝试过更换Hilt版本、使用
hiltViewModel()方法,问题仍未解决
相关代码
LoginViewModel.kt
@HiltViewModel class LoginViewModel @Inject constructor(private val authApi: AuthApi) : ViewModel() { private val _hidePassword = MutableLiveData(false) val hidePassword: LiveData<Boolean> get() = _hidePassword private val _autoLogin = MutableLiveData(false) val autoLogin: LiveData<Boolean> get() = _autoLogin private val _loginError = MutableLiveData(false) val loginError: LiveData<Boolean> get() = _loginError fun login(userId: String, password: String) { viewModelScope.launch { kotlin.runCatching { authApi.login( LoginReqeustDto( userId = userId, password = password ) ) }.onSuccess { // 省略成功逻辑 }.onFailure { e -> _loginError.value = true Log.d("LoginViewModel", e.message.toString()) } } } fun loginError(status: Boolean) { _loginError.value = status } fun autoLogin(status: Boolean) { _autoLogin.value = status } fun hidePassword(status: Boolean) { _hidePassword.value = status } }
NetworkModule.kt
@Module @InstallIn(SingletonComponent::class) class NetworkModule { @Provides @Singleton fun provideAuthApi(): AuthApi = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()).build() .create(AuthApi::class.java) @Provides @Singleton fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit { return Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient) .build() } @Singleton @Provides fun provideOkHttpClient( loggerInterceptor: HttpLoggingInterceptor, ): OkHttpClient { val okHttpClientBuilder = OkHttpClient().newBuilder() okHttpClientBuilder.connectTimeout(60, TimeUnit.SECONDS) okHttpClientBuilder.readTimeout(60, TimeUnit.SECONDS) okHttpClientBuilder.writeTimeout(60, TimeUnit.SECONDS) okHttpClientBuilder.addInterceptor(loggerInterceptor) return okHttpClientBuilder.build() } @Provides @Singleton fun provideLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } }
AuthActivity.kt
@AndroidEntryPoint class AuthActivity : ComponentActivity() { private val loginViewModel: LoginViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val navController = rememberNavController() NavHost( navController = navController, startDestination = NavigationRoute.loginRoute ) { composable(NavigationRoute.loginRoute) { LoginScreen( loginViewModel = loginViewModel, onNavigateToSignup = { navController.navigate(NavigationRoute.signupRoute) } ) } composable(NavigationRoute.signupRoute) { SignupScreen() } } } } }
解决方案
1. 确保Application类添加@HiltAndroidApp注解
这是Hilt依赖注入系统生效的核心前提,必须在自定义Application类上添加该注解,并在Manifest文件中指定:
@HiltAndroidApp class NewJeansBunniesApplication : Application() { // 自定义Application逻辑 }
在AndroidManifest.xml中配置:
<application android:name=".NewJeansBunniesApplication" <!-- 其他配置项 --> >
2. 修复NetworkModule中AuthApi的提供逻辑
当前provideAuthApi方法自行创建了未配置OkHttpClient的Retrofit实例,既存在代码重复也可能引发潜在问题,改为复用已配置好的Retrofit实例:
@Provides @Singleton fun provideAuthApi(retrofit: Retrofit): AuthApi = retrofit.create(AuthApi::class.java)
3. (可选)在Compose中正确使用hiltViewModel()
如果在Composable函数中获取ViewModel,建议直接使用hiltViewModel()而非从Activity传递,确保Hilt完成正确注入:
composable(NavigationRoute.loginRoute) { val loginViewModel: LoginViewModel = hiltViewModel() LoginScreen( loginViewModel = loginViewModel, onNavigateToSignup = { navController.navigate(NavigationRoute.signupRoute) } ) }
同时确保添加对应依赖:
implementation "androidx.hilt:hilt-navigation-compose:1.0.0"
内容的提问来源于stack exchange,提问作者HamTory
相关产品推荐
相关产品推荐

