如何在 SavedStateHandle-aware AndroidViewModel 中注入依赖项?
How to inject dependencies in a SavedStateHandle-aware AndroidViewModel?
假设视图模型如下:
public class FooViewModel extends AndroidViewModel {
@Inject public FooViewModel(Application app, SavedStateHandle handle, Bar bar) {
// ...
}
}
我想使用 Dagger 2 注入 Bar
。我正在开发 Android。
You should use SavedStateViewModelFactory
if you want to receive this object in ViewModel
's constructor.
但是,SavedStateViewModelFactory
docs 声明工厂是 final
,这意味着我也不能在那里注入 Bar
。
到目前为止,我一直在通过 setter:
进行注射
@Provides
FooViewModel provideFooViewModel(ViewModelStoreOwner owner, Bar bar) {
FooViewModel viewModel = new ViewModelProvider(owner).get(FooViewModel.class);
viewModel.setBar(bar);
return viewModel;
}
有更好的方法吗?
我想使用构造函数注入,将 Bar
实例变量标记为 final
并删除 setter.
要提供 FooViewModel
,您需要自定义实现 AbstractSavedStateViewModelFactory
。
MyComponent component = DaggerMyComponent.withViewModelStoreOwner(this)
.withSavedStateRegistryOwner(this)
.withDefaultArguments(this.arguments != null ? this.arguments : new Bundle())
.build();
和
@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);
});
}
注:
1.) 您只能在 AbstractSavedStateViewModelFactory
中得到 SavedStateHandle
,因此您无法将其放入图表中。
2.) 您可以使用 https://github.com/square/AssistedInject 减少该提供程序的长度。理论上 AutoFactory 也可以,但相比之下似乎没有维护。
3.) 您将无法在您的 ViewModel 上获得 @Inject
。
假设视图模型如下:
public class FooViewModel extends AndroidViewModel {
@Inject public FooViewModel(Application app, SavedStateHandle handle, Bar bar) {
// ...
}
}
我想使用 Dagger 2 注入 Bar
。我正在开发 Android。
You should use
SavedStateViewModelFactory
if you want to receive this object inViewModel
's constructor.
但是,SavedStateViewModelFactory
docs 声明工厂是 final
,这意味着我也不能在那里注入 Bar
。
到目前为止,我一直在通过 setter:
进行注射 @Provides
FooViewModel provideFooViewModel(ViewModelStoreOwner owner, Bar bar) {
FooViewModel viewModel = new ViewModelProvider(owner).get(FooViewModel.class);
viewModel.setBar(bar);
return viewModel;
}
有更好的方法吗?
我想使用构造函数注入,将 Bar
实例变量标记为 final
并删除 setter.
要提供 FooViewModel
,您需要自定义实现 AbstractSavedStateViewModelFactory
。
MyComponent component = DaggerMyComponent.withViewModelStoreOwner(this)
.withSavedStateRegistryOwner(this)
.withDefaultArguments(this.arguments != null ? this.arguments : new Bundle())
.build();
和
@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);
});
}
注:
1.) 您只能在 AbstractSavedStateViewModelFactory
中得到 SavedStateHandle
,因此您无法将其放入图表中。
2.) 您可以使用 https://github.com/square/AssistedInject 减少该提供程序的长度。理论上 AutoFactory 也可以,但相比之下似乎没有维护。
3.) 您将无法在您的 ViewModel 上获得 @Inject
。