Ric*_*iço 5 android mvvm dagger dagger-2 android-architecture-components
我正在尝试将新的Architecture Components添加ViewModel到我的应用程序中,同时用匕首注入它们.我的代码基于google 在这里显示的内容.我试图避免ViewModelFactory为每种ViewModel类型使用,所以我使用了ViewModelFactory它Map<Class<? extends ViewModel>, Provider<ViewModel>> creators.它适用于ViewModels具有@Singleton范围的依赖项.但是,我的一个人ViewModels有一个来自片段的依赖.这是该片段的模块:
@Module
public abstract class DownloadIssueDialogFragmentModule {
@Binds
abstract DialogFragment dialogFragment(DownloadIssueDialogFragment dialogFragment);
@Provides
@FragmentScope
static Issue provideIssue(DownloadIssueDialogFragment dialogFragment) {
return dialogFragment.getIssue();
}
}
Run Code Online (Sandbox Code Playgroud)
我的ViewModelModule:
@Module
public abstract class ViewModelModule {
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory factory);
@Binds
@IntoMap
@ViewModelKey(DownloadIssueViewModel.class)
abstract ViewModel bindDownloadIssueViewModel(DownloadIssueViewModel viewModel);
}
Run Code Online (Sandbox Code Playgroud)
匕首说不能提供Issue.它Map<Class<? extends ViewModel>, Provider<ViewModel>>似乎有意义,因为它似乎是在编译时创建的.但我只会知道该片段范围内的参数.我怎样才能做到这一点?
谢谢.
编辑:
最后,我采用了不同的方法.现在我为每个ViewModel创建一个工厂,而不是注入ViewModel,我注入了工厂.
我创建了这个库:AutoViewModelFactory
自动生成工厂.这是迄今为止我发现的最佳解决方案.
由于 Android 架构组件 ViewModel 比 Fragments 具有更大的范围(读取更持久的生命周期),因此您应该避免使 ViewModel 依赖于 Fragment 中的字段。
然而,如果Issue仅在运行时已知并且由片段中的逻辑生成,则您可以通过使用 Holder 模式来避免小的依赖循环问题。
这已经在其他一些 Dagger 2 StackOverflow 问题中讨论过,但您只需定义一个带有公共访问器/修改器的 Java bean:
class IssueHolder {
private Issue issue;
@Inject
IssueHolder() {} //empty explicit constructor as required by Dagger 2
public void setIssue(@Nullable Issue issue) {
this.issue = issue;
}
@Nullable
public Issue getIssue() {
return issue;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以让你的 ViewHolder 依赖于IssueHolder而不是直接依赖于Issue:
@Inject IssueHolder issueHolder;
public void doSomething() {
if (issueHolder.get() == null) {
throw new IllegalStateException("Expected IssueHolder to be set by IssueFragment at this point");
}
//TODO: the logic you want here
}
Run Code Online (Sandbox Code Playgroud)
与任何模式一样,应谨慎使用此 Holder 模式,因为它很容易退化。最好的解决方案是,如果可能的话,以消除循环可能性的方式设计模块和依赖项,
| 归档时间: |
|
| 查看次数: |
1359 次 |
| 最近记录: |