HiltViewModel:无法创建 class 的实例
HiltViewModel: Cannot create an instance of class
我正在使用 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()
}
已注入 class:
@Singleton
class RealtimeDatabaseRepository @Inject constructor() { }
当我从 ViewModel 构造函数中删除 private val repository: RealtimeDatabaseRepository
时它正在工作
当我更新到 2.31.2-alpha
时,我使用的是刀柄版本 2.30.1-alpha
,按照 USMAN osman 的建议,错误消失了。
有了新的刀柄版本,很多东西都发生了变化。
您还必须将 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()
}
}
这是文档中关于 ViewModelComponent
和 ViewModelScoped
的内容
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.
link: https://dagger.dev/hilt/view-model.html
然后你的视图模型:
@HiltViewModel
class RepoViewModel @Inject constructor(
application: Application,
private val reposiotryIMPL: ReposiotryIMPL
) : AndroidViewModel(application) {}
更新
您不必像我在上面的示例中那样使用 ViewModelComponent
或 ViewModelScoped
。您还可以使用其他 scopes
或 components
取决于您的用例。
此外阅读文档,我把匕首柄的link放在上面。
当使用 ViewModel 的 Fragment/Activity 缺少 @AndroidEntryPoint注解,例如:
import androidx.fragment.app.viewModels
@AndroidEntryPoint
class SampleFragment: BaseFragment() {
val viewModel: SampleFragmentViewModel by viewModels()
}
如果注释不存在,则会发生与您描述的完全相同的错误。
我正在使用 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()
}
已注入 class:
@Singleton
class RealtimeDatabaseRepository @Inject constructor() { }
当我从 ViewModel 构造函数中删除 private val repository: RealtimeDatabaseRepository
时它正在工作
当我更新到 2.31.2-alpha
时,我使用的是刀柄版本 2.30.1-alpha
,按照 USMAN osman 的建议,错误消失了。
有了新的刀柄版本,很多东西都发生了变化。
您还必须将 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()
}
}
这是文档中关于 ViewModelComponent
和 ViewModelScoped
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.
link: https://dagger.dev/hilt/view-model.html
然后你的视图模型:
@HiltViewModel
class RepoViewModel @Inject constructor(
application: Application,
private val reposiotryIMPL: ReposiotryIMPL
) : AndroidViewModel(application) {}
更新
您不必像我在上面的示例中那样使用 ViewModelComponent
或 ViewModelScoped
。您还可以使用其他 scopes
或 components
取决于您的用例。
此外阅读文档,我把匕首柄的link放在上面。
当使用 ViewModel 的 Fragment/Activity 缺少 @AndroidEntryPoint注解,例如:
import androidx.fragment.app.viewModels
@AndroidEntryPoint
class SampleFragment: BaseFragment() {
val viewModel: SampleFragmentViewModel by viewModels()
}
如果注释不存在,则会发生与您描述的完全相同的错误。