我刚开始使用Dagger Framework进行依赖注入,因此可能缺少一些琐碎的东西,但是我花了2天多的时间来研究代码和教程。
因此,我试图在我的ViewModel
中使用匕首依赖注入,我发现我可以使用已实现的称为多重绑定的功能来实现这一点。我有一个AppComponent
和一个ActivitySubComponent
。 AppComponent
安装了一个ViewModelFactoryModule
和一个@Binds
的{{1}},我希望此ViewModelProvider.Factory
在应用程序中,因为我认为它应该独立于{{1} } 生命周期。在我的Module
中有一个Activity
和ActivitySubComponent
一个ViewModelsModule
。
现在,根据我的理解,我在@Binds
中加入了ViewModel
,这会将子组件添加到ActivitySubComponent
中。
编辑:
现在,当我制作/构建项目时,出现以下错误。抱歉,最初的错误是:
ViewModelFactoryModule
在AppComponent
error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
com.mobile.presentation.viewmodels.build.ViewModelFactory(creators)
com.mobile.presentation.viewmodels.build.ViewModelFactory is provided at
com.mobile.app.AppComponent.obtainViewModelsFactory()
中添加以下方法后,产生了以下错误。
AppComponent.java
足够的jibber jabber,下面是相关代码:
AppComponent.java
Map<Class<? extends ViewModel>, Provider<ViewModel>> obtainMap();
ViewModelFactoryModule.java
error: [Dagger/MissingBinding] java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method.
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is provided at
com.mobile.app.AppComponent.obtainMap()
It is also requested at:
com.mobile.presentation.viewmodels.build.ViewModelFactory(creators)
The following other entry points also depend on it:
com.mobile.app.AppComponent.obtainViewModelsFactory()
ViewModelsFactory.java
@AppScope
@Component(
modules = {
AppModule.class,
ViewModelFactoryModule.class
})
public interface AppComponent {
App obtainApp();
ViewModelFactory obtainViewModelsFactory();
// I tried with adding the following line, out of sheer annoyance.
// Map<Class<? extends ViewModel>, Provider<ViewModel>> obtainMap();
}
ActivitySubComponent.java
@Module(subcomponents = ActivitySubComponent.class)
public abstract class ViewModelFactoryModule {
@AppScope
@Binds
public abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory viewModelFactory);
}
ViewModelsModule.java
@AppScope
public class ViewModelFactory implements ViewModelProvider.Factory {
private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators;
@Inject
public ViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {
this.creators = creators;
}
@SuppressWarnings("unchecked")
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass)
{
Provider<? extends ViewModel> creator = creators.get(modelClass);
if (creator == null) {
for (Map.Entry<Class<? extends ViewModel>, Provider<ViewModel>> entry : creators.entrySet()) {
if (modelClass.isAssignableFrom(entry.getKey())) {
creator = entry.getValue();
break;
}
}
}
if (creator == null) {
throw new IllegalArgumentException("unknown model class " + modelClass);
}
try {
return (T) creator.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
现在,据此我了解到// I have a separate module for my `LiveData`.
@ActivityScope
@Subcomponent(
modules = {
ActivityModule.class,
ViewModelsModule.class,
SplashLiveDataModule.class
}
)
public interface ActivitySubComponent {
Activity obtainActivity();
LiveData<InitialAPIResponse> obtainLiveInitialApiResponse();
LiveData<InitialSplashApiStatus> obtainLiveInitialSplashApiStatus();
@Subcomponent.Builder
interface Builder {
ActivitySubComponent build();
Builder setActivityModule(ActivityModule activityModule);
}
}
无法直接访问@Module
public abstract class ViewModelsModule {
@ActivityScope
@Binds
@IntoMap
@ViewModelKey(SplashViewModel.class)
public abstract ViewModel provideVideoListViewModel(SplashViewModel viewModel);
}
,但是它应该能够访问AppComponent
,因为生成的ActivitySubComponent
是组件的内部类(也许我缺少了一些东西),我不认为SubComponent
应该绑定到应用程序的组件(我之所以这样说是因为如果我将@Subcomponent
移到ViewModel
我也可以运行代码,并且一切正常。),我的逻辑方法是否错误?
匕首依赖项:
ViewModelsModule
答案 0 :(得分:1)
你是对的。在ActivitySubComponent
中添加ViewModelFactoryModule
会将子组件添加到AppComponent。
要向父级添加子组件时,有两种方法。 首先,在模块中添加子组件,然后将该模块添加到父级。其次,通过在父组件中声明一个抽象方法来返回子组件。
您已经正确使用了第一部分,但是在AppComponent
中,您已经创建了一个返回ViewModelFactory的方法,该方法已经由ViewModelFactoryModule提供。这与对象图冲突,并且由于您的构建失败。您需要同时删除两个返回ViewModelFactory和Map的方法,这将解决此问题。