我正在学习匕首依赖注射(我知道我迟到了,现在开始更好)。
但我面临以下错误。如有任何帮助或建议,我们将不胜感激。
错误日志
error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] @com.mypackage.di.key.ItemDetail java.lang.Integer cannot be provided without an @Provides-annotated method.
public interface ApplicationComponent extends AndroidInjector<RetailShopApplication> {
^
@com.mypackage.di.key.ItemDetail java.lang.Integer is injected at
com.mypackage.ui.detail.ItemDetailViewModel.<init>(…, itemId)
com.mypackage.ui.detail.ItemDetailViewModel is injected at
com.mypackage.di.module.ViewModelModule.provideItemDetailViewModel(itemDetailViewModel)
java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
com.mypackage.viewModel.ViewModelFactory.<init>(creators)
com.mypackage.viewModel.ViewModelFactory is injected at
com.mypackage.ui.home.ItemCategoryFragment.itemViewFactory
com.mypackage.ui.home.ItemCategoryFragment is injected at
dagger.android.AndroidInjector.inject(T)
component path: com.mypackage.di.component.ApplicationComponent ? com.mypackage.di.builder.ActivityBuilder_ContributeHomeActivity.HomeActivitySubcomponent ? com.mypackage.ui.home.HomeFragmentProvider_ContributeItemCategoryFragment.ItemCategoryFragmentSubcomponent
我的问题
我在ViewModelModule中创建了一个带有contribAndroidInjection批注的provideItemDetailViewModel(),但是ItemDetailViewModel构造函数有一个整数值。
所以我在运行时从我的活动意图到ItemDetailActivityModule类提供一个整数值。问题是匕首给我一个错误“整数已经存在于范围内”但是无法注入ViewModel构造函数。
ViewModelModule
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(ItemCategoryViewModel.class)
abstract ViewModel provideItemCategoryViewModel(ItemCategoryViewModel
itemCategoryViewModel);
@Binds
@IntoMap//<---- Here is the new ViewModel
@ViewModelKey(ItemDetailViewModel.class)
abstract ViewModel provideItemDetailViewModel(ItemDetailViewModel
itemDetailViewModel);
@Binds
abstract ViewModelProvider.NewInstanceFactory
getViewModelFactory(ViewModelFactory viewModelFactory);
}
项目细节视图模型
@Inject
public ItemDetailViewModel(Application application, @ItemDetail int itemId)
{
itemRepository = new ItemRepository(application);
itemLiveData = itemRepository.getItem(itemId);
}
ItemDetailActivityModule
@Module
public class ItemDetailActivityModule {
@Provides
@ItemDetail
int provideItemId(ItemDetailActivity itemDetailActivity) {
return itemDetailActivity.getIntent().getIntExtra(AppConstants.ITEM_ID,
0);
}
}
ActivityBuilder
@Module
public abstract class ActivityBuilder {
@ActivityScope
@ContributesAndroidInjector(modules = {HomeFragmentProvider.class,
HomeActivityModule.class})
abstract HomeActivity contributeHomeActivity();
@ActivityScope
@ContributesAndroidInjector(modules = ItemDetailActivityModule.class)
abstract ItemDetailActivity contributeItemDetailActivity();
}
ApplicationComponent
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class,
ApplicationModule.class, ActivityBuilder.class})
public interface ApplicationComponent extends
AndroidInjector<RetailShopApplication> {
@Component.Builder
abstract class Builder extends
AndroidInjector.Builder<RetailShopApplication> {
}
}
ApplicationModule
@Module(includes = ViewModelModule.class)
public class ApplicationModule {
@Provides
Application provideApplication(RetailShopApplication application) {
return application;
}
}
问题是我正在为ViewModelModule类中的每个ViewModel创建提供程序,该类包含在AppModule中。
使用@ContributeAndroidInjection创建的每个Activity都是一个子组件。
所以App组件和Activity子组件是不同的。 Activity组件可以访问App组件的提供者但反之亦然,注入的原因已经存在错误
我解决了问题,包括活动模块内的视图模型而不是appcomponent模块。
之前
@Module
public abstract class ViewModelModule {
@Binds
@IntoMap//<---- Here is the new ViewModel
@ViewModelKey(ItemDetailViewModel.class)
abstract ViewModel provideItemDetailViewModel(ItemDetailViewModel
itemDetailViewModel);
@Binds
abstract ViewModelProvider.NewInstanceFactory
getViewModelFactory(ViewModelFactory viewModelFactory);
}
之后 - 在ViewModelModule中只需要ViewModelFactory将所有ViewModel提供程序移动到活动模块。
@Module
public abstract class ViewModelModule {
@Binds
abstract ViewModelProvider.NewInstanceFactory
getViewModelFactory(ViewModelFactory viewModelFactory);
}
创建Abstract类以保存ViewModel提供程序
@Module
public abstract class ItemDetailProvider {
@Binds
@IntoMap
@ViewModelKey(ItemDetailViewModel.class)
abstract ViewModel provideItemDetailViewModel(ItemDetailViewModel
itemDetailViewModel);
}
现在在Activity模块中添加创建的提供程序,如下所示
之前
@Module
public abstract class ActivityBuilder {
@ContributesAndroidInjector(modules =
{ItemDetailActivityModule.class})
abstract ItemDetailActivity contributeItemDetailActivity();
}
之后 - 现在添加与上述活动对应的ViewModel,在我的情况下,它是Item Detail ViewModel类
@Module
public abstract class ActivityBuilder {
@ContributesAndroidInjector(modules =
{ItemDetailActivityModule.class,ItemDetailProvider.class})//<--- provider added in this line
abstract ItemDetailActivity contributeItemDetailActivity();
}