Ошибка сборки Dagger-android не может быть предоставлена ​​без аннотированного метода @ Provides - PullRequest
0 голосов
/ 28 апреля 2019

Я изучаю инъекцию зависимости от кинжала (я знаю, что опаздываю на вечеринку, лучше начать сейчас).

Но я столкнулся с ошибкой ниже. Пожалуйста, любая помощь или предложение может быть с благодарностью.

ОШИБКА Log

    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

Моя проблема

Я создал provideItemDetailViewModel () с аннотацией contribAndroidInjection в ViewModelModule, но конструктор 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);
}

ItemDetailViewModel

@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;
   }
}

1 Ответ

1 голос
/ 29 апреля 2019

Решение

Проблема в том, что я создавал провайдера для каждой ViewModel в классе ViewModelModule, который включен в AppModule.

Каждая активность, созданная с помощью @ContributeAndroidInjection, является подкомпонентом.

Таким образом, компонент App и компонент Sub Activity различаются.Компонент Activity может получить доступ к поставщику компонента App, но не наоборот, что причина внедрения уже существует. Ошибка

Я решил проблему, включив модель представления внутри модуля действия вместо модуля appcomponent.

ViewModelModule

До

@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.

@Module
public abstract class ViewModelModule {

   @Binds
   abstract ViewModelProvider.NewInstanceFactory 
   getViewModelFactory(ViewModelFactory viewModelFactory);
}

ItemDetailProvider

Создать абстрактный класс для хранения поставщиков ViewModel

@Module
public abstract class ItemDetailProvider {

  @Binds
  @IntoMap
  @ViewModelKey(ItemDetailViewModel.class)
  abstract ViewModel provideItemDetailViewModel(ItemDetailViewModel 
  itemDetailViewModel);

}

ActivityModule

Теперь добавьте созданного поставщика вмодуль Activity, как показано ниже

До

@Module
public abstract class ActivityBuilder {

   @ContributesAndroidInjector(modules = 
   {ItemDetailActivityModule.class})
   abstract ItemDetailActivity contributeItemDetailActivity();

}

После - Теперь добавьте ViewModel, который corespond, к вышеуказанной активности в моем случае этоэто ItemDetailViewModel class

@Module
public abstract class ActivityBuilder {

   @ContributesAndroidInjector(modules = 
   {ItemDetailActivityModule.class,ItemDetailProvider.class})//<--- provider added in this line
   abstract ItemDetailActivity contributeItemDetailActivity();

}
...