【发布时间】:2020-07-19 12:40:33
【问题描述】:
使用新的依赖注入库Hilt,如何在没有构造函数参数和ViewModelFactory的情况下将一些类注入ViewModel?
有可能吗?
与Fragment 一样,我们仅使用@AndroidEntryPoint 和@Inject。
【问题讨论】:
标签: android dagger-hilt
使用新的依赖注入库Hilt,如何在没有构造函数参数和ViewModelFactory的情况下将一些类注入ViewModel?
有可能吗?
与Fragment 一样,我们仅使用@AndroidEntryPoint 和@Inject。
【问题讨论】:
标签: android dagger-hilt
如何在没有构造函数参数和 ViewModelFactory 的情况下将一些类注入 ViewModel?有可能吗?
Hilt 支持通过 @HiltViewModel(以前的 @ViewModelInject)注解对 ViewModel 进行构造函数注入。
这允许任何 @AndroidEntryPoint-annotated 类将其 defaultViewModelProviderFactory 重新定义为 HiltViewModelFactory,从而允许创建 @HiltViewModel-annotated ViewModels 通过 Dagger/Hilt 正确实例化。
新的 HILT 版本:
@HiltViewModel
class RegistrationViewModel @Inject constructor(
private val someDependency: SomeDependency,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
...
}
旧 HILT 版本:
class RegistrationViewModel @ViewModelInject constructor(
private val someDependency: SomeDependency,
@Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
...
}
然后
@AndroidEntryPoint
class ProfileFragment: Fragment(R.layout.profile_fragment) {
private val viewModel by viewModels<RegistrationViewModel>() // <-- uses defaultViewModelProviderFactory
【讨论】:
viewModels<>()是什么,无法导入
import androidx.fragment.app.viewModels in implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
androidx.fragment:fragment-ktx:1.2.5
@HiltViewModel。虽然我看到我的答案已经过时,但我应该更新它。
是的,可以在没有构造函数参数的情况下将依赖项注入ViewModel 类。首先我们需要创建一个带有@EntryPoint注解的新接口来访问它。
入口点是一个接口,每个接口都有一个访问器方法 我们想要的绑定类型(包括它的限定符)。还有,界面 必须用
@InstallIn注释以指定要在其中的组件 安装入口点。
最佳做法是在使用它的类中添加新的入口点接口。
public class HomeViewModel extends ViewModel {
LiveData<List<MyEntity>> myListLiveData;
@ViewModelInject
public HomeViewModel(@ApplicationContext Context context) {
myListLiveData = getMyDao(context).getAllPosts();
}
public LiveData<List<MyEntity>> getAllEntities() {
return myListLiveData;
}
@InstallIn(ApplicationComponent.class)
@EntryPoint
interface MyDaoEntryPoint {
MyDao myDao();
}
private MyDao getMyDao(Context appConext) {
MyDaoEntryPoint hiltEntryPoint = EntryPointAccessors.fromApplication(
appConext,
MyDaoEntryPoint.class
);
return hiltEntryPoint.myDao();
}
}
在上面的代码中,我们创建了一个名为getMyDao 的方法,并使用EntryPointAccessors 从应用程序容器中检索MyDao。
请注意,该接口使用
@EntryPoint进行注释,并且它是 安装在ApplicationComponent因为我们想要依赖 来自 Application 容器的实例。
@Module
@InstallIn(ApplicationComponent.class)
public class DatabaseModule {
@Provides
public static MyDao provideMyDao(MyDatabase db) {
return db.MyDao();
}
}
虽然上面的代码已经过测试并且可以正常工作,但是android官方不推荐将依赖注入到ViewModel中;除非我们知道自己在做什么,否则最好的方法是通过构造函数注入将依赖项注入ViewModel。
【讨论】: