Hilt ViewModel 没有零参数构造函数

ary*_*axt 13 android android-viewmodel dagger-hilt

Cannot create an instance of class com.comp.app.winners.WinnersViewModel
Caused by: java.lang.InstantiationException: java.lang.Class<com.comp.app.winners.WinnersViewModel> has no zero argument constructor
Run Code Online (Sandbox Code Playgroud)

尝试使用 hilt 解析片段上的视图模型时出现错误

// Proj
ext.hilt_version = '2.32-alpha'
ext.lifecycle_version = "2.2.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"

// App
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"
implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha03'
implementation "androidx.fragment:fragment-ktx:1.1.0"

@HiltAndroidApp
class MyApplication : Application()

@Module
@InstallIn(SingletonComponent::class)
class ApplicationModule {
    @Provides
    fun provideService(): MyService = MyServiceImpl()
}

@AndroidEntryPoint
class HomeActivity : AppCompatActivity() {

    // Fragment is added here
    private fun openFragment(fragment: Fragment) =
        supportFragmentManager.beginTransaction().apply {
            replace(R.id.container, fragment)
            addToBackStack(null)
            commit()
        }
}

@AndroidEntryPoint
class WinnersFragment: Fragment() {
    private val viewModel: WinnersViewModel by viewModels()
}

@HiltViewModel
class WinnersViewModel @Inject constructor(
    private val service: MyService
) : ViewModel()
Run Code Online (Sandbox Code Playgroud)

还需要对片段执行其他操作吗?我需要以某种方式提供 viewModel 吗?

注意:这是崩溃/运行时错误,而不是编译错误

dea*_*rne 19

我的问题与我的 ViewModel 无关,而是与它所应用的片段有关。

我的 ViewModel 看起来像

@HiltViewModel
class MyViewModel @Inject constructor(repository: MyRepository): ViewModel() {
Run Code Online (Sandbox Code Playgroud)

这是正确的,但我仍然遇到异常Caused by: java.lang.InstantiationException: java.lang.Class<com.myapp.MyViewModel> has no zero argument constructor

但是,我错过了AndroidEntryPoint片段上的注释。添加回来解决了我的问题,即

@AndroidEntryPoint
class MyFragment: Fragment() {

    private val viewModel: MyViewModel by viewModels()

    ...
}
Run Code Online (Sandbox Code Playgroud)


met*_*ure 7

如果在使用 compose 时出现此错误,可能是因为您使用的是NavHostand NavHostController。根据官方文档

如果 @HiltViewModel 注解的 ViewModel 的作用域为导航图,请使用 hiltViewModel 可组合函数,该函数可处理使用 @AndroidEntryPoint 注解的片段或活动。

hiltViewModel是专用 Hilt + Compose Navigation 依赖项的一部分:

dependencies {
    // 1.0.0-beta01 at time of this writing.
    // official docs linked above appear to auto update the version
    implementation("androidx.hilt:hilt-navigation-compose:[version]")
}
Run Code Online (Sandbox Code Playgroud)

hiltViewModel以下是同一文档中提供的调用的上下文示例:

// import androidx.hilt.navigation.compose.hiltViewModel

@Composable
fun MyApp() {
    NavHost(navController, startDestination = startRoute) {
        composable("example") { backStackEntry ->
            // Creates a ViewModel from the current BackStackEntry
            // Available in the androidx.hilt:hilt-navigation-compose artifact
            val exampleViewModel = hiltViewModel<ExampleViewModel>()
            ExampleScreen(exampleViewModel)
        }
        /* ... */
    }
}
Run Code Online (Sandbox Code Playgroud)


ian*_*ake 2

您需要升级到 Fragment 1.2.0 或更高版本。

根据Lifecycle 2.2.0 发行说明ViewModelProvider, Hilt 在后台使用的新API 仅在使用 Fragment 1.2.0 或更高版本时适用。当使用旧版本的 Fragment 时,这些 API 不会连接到 Fragment,因此当您使用by viewModels().

您应该升级到 Fragment 1.2.5(Fragment 1.2.X 集的最后一个版本)或 Fragment 1.3.0,这两个版本都包含使 Hilt 正常工作所需的 API 挂钩。