首页 > 解决方案 > HiltViewModel:无法创建类的实例

问题描述

我正在使用 Hilt。更新到后,我收到了已弃用的1.0.0-alpha03警告,我应该使用. 但是当我改变它时,我得到了一个错误:@ViewModelInject@HiltViewModel

java.lang.RuntimeException: Cannot create an instance of class com.example.LoginViewModel
...
Caused by: java.lang.NoSuchMethodException: com.example.LoginViewModel.<init> [class android.app.Application]

以前我的 ViewModel 看起来像这样:

class LoginViewModel @ViewModelInject constructor(
    application: Application,
    private val repository: RealtimeDatabaseRepository
) : AndroidViewModel(application)

现在看起来像这样:

@HiltViewModel
class LoginViewModel @Inject constructor(
    application: Application,
    private val repository: RealtimeDatabaseRepository
) : AndroidViewModel(application)

注入 ViewModel 的片段:

@AndroidEntryPoint
class LoginFragment : Fragment(R.layout.fragment_login)
{
    private val viewModel: LoginViewModel by activityViewModels()
}

注入类:

@Singleton
class RealtimeDatabaseRepository @Inject constructor() { }

private val repository: RealtimeDatabaseRepository当我从 ViewModel 构造函数中删除它时,它正在工作


正如USMAN osman2.30.1-alpha建议的那样,当我更新到时,我正在使用hilt 版本,错误消失了。2.31.2-alpha

标签: androidkotlindagger-hilt

解决方案


有了新的刀柄版本,很多东西都被改变了。
您还必须将您的 hilt android、hilt 编译器和 hilt gradle 插件升级到:2.31-alpha
我完全按照您的方式制作了模拟样本我遇到了同样的问题,在浏览了 hilt 的文档后,我发现了将依赖项注入 viewModels 的新方法,您必须制作用于依赖项的单独模块,这些依赖项将注入viewModel带有特殊组件的称为ViewModelComponent

@Module
@InstallIn(ViewModelComponent::class) // this is new
object RepositoryModule{

    @Provides
    @ViewModelScoped // this is new
    fun providesRepo(): ReposiotryIMPL { // this is just fake repository
        return ReposiotryIMPL()
    }

}

这是文档所说的ViewModelComponentViewModelScoped

All Hilt View Models are provided by the ViewModelComponent which follows the same lifecycle as a ViewModel, i.e. it survives configuration changes. To scope a dependency to a ViewModel use the @ViewModelScoped annotation.

A @ViewModelScoped type will make it so that a single instance of the scoped type is provided across all dependencies injected into the Hilt View Model.
链接:https ://dagger.dev/hilt/view-model.html

然后你的视图模型:

@HiltViewModel
class RepoViewModel @Inject constructor(
    application: Application,
    private val reposiotryIMPL: ReposiotryIMPL
) : AndroidViewModel(application) {}

更新
您应该使用ViewModelComponentViewModelScoped像我在上面的示例中所做的那样,这不是强制性的。您也可以使用其他scopescomponents取决于您的用例。
此外阅读文档,我把匕首的链接放在上面。


推荐阅读