android - 如何使构造函数中带有 id 参数的 ViewModelFactory 可注入?
问题描述
我在带有 Dagger 的 Android 中使用 ViewModel 来管理依赖项。我的 ViewModel 将在创建时从 MainActivity 获取一个 id。所以我在这里有这些代码:
在活动中:
@inject ViewModelProviderFactory mViewModelFactory;
ViewModelProviders.of(this, mViewModelFactory).get(MyViewModel.class);
我的工厂供应商:
public class ViewModelProviderFactory implements ViewModelProvider.Factory {
private int id;
@inject
public ViewModelProviderFactory(int id) {
this.id = id;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return new MyViewModel(id);
}
}
为了工作,我需要向我的模块添加一个参数:
@Module
public class MainActivityModule {
int id;
public MainActivityModule(int id){
this.id = id;
}
@Provides
ViewModelProvider.Factory mainViewModelProvider() {
return new ViewModelProviderFactory<>(id);
}
}
或者我可以直接在组件中做它并使其抽象。在新的 Dagger 中,我可以使用 Dagger 类来制作活动或片段组件。因此,我应该为每个活动创建子组件,并为我应该编写的其他代码创建一个 Builder 和音调。
是否有任何简单和更好的方法来防止这些额外的代码,或者我最好通过在这样的活动中调用一个新工厂来创建我的工厂?:
ViewModelProviders.of(this, new ViewModelProviderFactory(id)).get(MyViewModel.class);
解决方案
new ViewModelProviderFactory(id)
在我看来,从那里调用Activity
是更简单的解决方案。但是,我不会直接从Activity
. 相反,我会创建工厂(是的,工厂的工厂......),我会注入Activity
.
这是一个例子:
class FactoryOfFactory {
@Inject
FactoryOfFactory() {}
ViewModelProvider.Factory create(int id) {
// ViewModelProviderFactory can now by just an anonymous class
return new ViewModelProvider.Factory() {
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return (T) new MyViewModel(id);
}
};
}
}
以及用法:
class ClientActivity extends AppCompatActivity {
@Inject
FactoryOfFactory factoryOfFactory;
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final int id = 123;
ViewModelProviders.of(this, factoryOfFactory.create(id)).get(MyViewModel.class);
}
}
该方法也有如下解决方案:如果MyViewModel
需要其他依赖(不提供Activity
),我们可以很容易地添加它们(无需修改Activity
):
class MyViewModel extends ViewModel {
MyViewModel(int id, AnotherDependency anotherDependency) { }
}
class FactoryOfFactory {
private final AnotherDependency anotherDependency; // added
@Inject
FactoryOfFactory(final AnotherDependency anotherDependency) { // modified
this.anotherDependency = anotherDependency; // added
}
ViewModelProvider.Factory create(int id) {
// ViewModelProviderFactory can now by just an anonymous class
return new ViewModelProvider.Factory() {
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return (T) new MyViewModel(id, anotherDependency); // modified
}
};
}
}
而且,当然,我相信一个比FactoryOfFactory
存在更好的名字;)
推荐阅读
- sharepoint - 编辑在 SharePoint 文档库中创建的 HTML 生成的 Word 文件会损坏图像
- java - 如何在不使用 Collections.swap() 的情况下随机化 ArrayList?
- azure - DockerCompose@0 后天蓝色管道未继续
- android - Proguard 语法:如何过滤“{ *; }”、“{ }”和“
“ 工作? - c# - 应该使用哪个“sqlite”在使用 Visual Studio for Mac 在 MacO 上构建应用程序?
- html - 如何将填充添加到选择的选项?
- r - 为什么For循环返回相同的函数
- javascript - 如何显示具有 4 个角坐标的 mapboxgl 对象的边界框?
- c# - 为什么我的 ASP.NET Core 3.1 控制器会自动为从视图返回的 EF Core 模型分配 ID?
- python - 如何在 python 目录中查找所有文件的单词上下文,而不仅仅是一个目录?