[英]How to inject dependencies in a SavedStateHandle-aware AndroidViewModel?
Assume a view model like this:假设像这样的视图 model :
public class FooViewModel extends AndroidViewModel {
@Inject public FooViewModel(Application app, SavedStateHandle handle, Bar bar) {
// ...
}
}
I want to inject Bar
using Dagger 2. I am developing on Android.我想使用 Dagger 2 注入
Bar
。我正在 Android 上进行开发。
According to the SavedStateHandle
docs :根据
SavedStateHandle
文档:
You should use
SavedStateViewModelFactory
if you want to receive this object inViewModel
's constructor.如果你想在
ViewModel
的构造函数中接收这个 object ,你应该使用SavedStateViewModelFactory
。
However, the SavedStateViewModelFactory
docs state that the factory is final
which means I cannot inject Bar
there, either.但是,
SavedStateViewModelFactory
文档state 工厂是final
的,这意味着我也不能在那里注入Bar
。
So far, I have been injecting via a setter:到目前为止,我一直在通过 setter 进行注入:
@Provides
FooViewModel provideFooViewModel(ViewModelStoreOwner owner, Bar bar) {
FooViewModel viewModel = new ViewModelProvider(owner).get(FooViewModel.class);
viewModel.setBar(bar);
return viewModel;
}
Is there a better way to do this?有一个更好的方法吗?
I want to use constructor injection, mark the Bar
instance variable as final
and eliminate the setter.我想使用构造函数注入,将
Bar
实例变量标记为final
并消除 setter。
To provide a FooViewModel
, you need a custom implementation of AbstractSavedStateViewModelFactory
.要提供
FooViewModel
,您需要AbstractSavedStateViewModelFactory
的自定义实现。
MyComponent component = DaggerMyComponent.withViewModelStoreOwner(this)
.withSavedStateRegistryOwner(this)
.withDefaultArguments(this.arguments != null ? this.arguments : new Bundle())
.build();
and和
@Provides
@Suppress("UNCHECKED_CAST")
public MyViewModel viewModel(ViewModelStoreOwner viewModelStoreOwner, SavedStateRegistryOwner savedStateRegistryOwner, Bundle defaultArgs, Application application, Bar bar) {
return new ViewModelProvider(
viewModelStoreOwner,
new AbstractSavedStateViewModelFactory(savedStateRegistryOwner, defaultArgs) {
@Override
public <T extends ViewModel> T create(
String key,
Class<T> modelClass,
SavedStateHandle handle) {
return (T) new MyViewModel(application, handle, bar);
}
}).get(MyViewModel.class);
});
}
Note:笔记:
1.) you only get SavedStateHandle
inside the AbstractSavedStateViewModelFactory
, so you won't be able to get it into your graph. 1.)您只能在
AbstractSavedStateViewModelFactory
中获得SavedStateHandle
,因此您将无法将其放入您的图表中。
2.) you can reduce the length of that provider by using https://github.com/square/AssistedInject . 2.) 您可以使用https://github.com/square/AssistedInject来缩短该提供程序的长度。 Theoretically AutoFactory would also work, but it seems unmaintained in comparison.
理论上 AutoFactory 也可以工作,但相比之下似乎没有维护。
3.) you won't be able to get @Inject
on your ViewModel. 3.) 您将无法在 ViewModel 上获得
@Inject
。
This answer was partly adapted from https://github.com/Zhuinden/DaggerViewModelExperiment/blob/c3cbf0a5bc85467cec08755fcc152db5e8c55f91/app/src/main/java/com/zhuinden/daggerviewmodelexperiment/features/second/SecondFragment.kt#L32-L47 .该答案部分改编自https://github.com/Zhuinden/DaggerViewModelExperiment/blob/c3cbf0a5bc85467cec08755fcc152db5e8c55f91/app/src/main/java/com/zhuinden/daggerviewSecdFragment/kont#L32/ 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.