android dependency-injection dagger-2 dagger dagger.android

android - Daga: IllegalArgumentException: No hay ningún inyector con destino a clase



dependency-injection dagger-2 (2)

Creo que has olvidado poner la anotación @ContributesAndroidInjector :

@Module public abstract class ActivityModule { @ContributesAndroidInjector abstract ProductListActivity contributeProductListActivity(); @ContributesAndroidInjector abstract ProductDetailsActivity contributeProductDetailsActivity(); }

E incluye ViewModelModule dentro de AppModule :

@Module(includes = ViewModelModule.class) class AppModule { ... }

Mira este código que has escrito:

@Provides @Singleton ProductListRepository provideProductListRepository(ProductListRepository repository) { return repository; }

¿Qué esperas que pase? Le está diciendo a dagger "hey, dagger, cada vez que le pido que me proporcione ProductListRepository luego cree (devuelva) ese objeto utilizando ProductListRepository " . Eso no va a funcionar.

Lo más probable es que lo que pretendía era "hey, dagger, siempre que le pida que me proporcione una implementación de ProductListRepository luego cree (devuelva) ese objeto utilizando ProductListRepositoryImpl " :

@Provides @Singleton ProductListRepository provideProductListRepository(ProductListRepositoryImpl repository) { return repository; }

Que puede ser sustituido con lo siguiente:

@Binds @Singleton abstract ProductListRepository provideProductListRepository(ProductListRepositoryImpl repository);

Soy nuevo en Dagger 2. Tengo 2 actividades, quiero usar ViewModel inyectado para ambos. Aquí está mi ViewModuleFactory :

@Singleton public class ProductViewModelFactory implements ViewModelProvider.Factory { private final Map<Class<? extends ViewModel>, Provider<ViewModel>> creators; @Inject public ProductViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) { this.creators = creators; } @SuppressWarnings("unchecked") @Override public <T extends ViewModel> T create(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 viewmodel class " + modelClass); } try { return (T) creator.get(); } catch (Exception e) { throw new RuntimeException(e); } } }

Mi ViewModelModule :

@Module abstract class ViewModelModule { @Binds @IntoMap @ViewModelKey(ProductListViewModel.class) abstract ViewModel bindProductListViewModel(ProductListViewModel listViewModel); @Binds @IntoMap @ViewModelKey(ProductDetailsViewModel.class) abstract ViewModel bindProductDetailsViewModel(ProductDetailsViewModel detailsViewModel); @Binds abstract ViewModelProvider.Factory bindViewModelFactory(ProductViewModelFactory factory); }

Mi ViewModelKey para mapeo:

@Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @MapKey @interface ViewModelKey { Class<? extends ViewModel> value(); }

Mi módulo de actividad :

@Module public abstract class ActivityModule { abstract ProductListActivity contributeProductListActivity(); abstract ProductDetailsActivity contributeProductDetailsActivity(); }

Mi módulo de aplicación :

@Module class AppModule { @Provides @Singleton RedMartProductService provideRedMartProductService() { ........ } @Provides @Singleton ProductListRepository provideProductListRepository(ProductListRepository repository) { return repository; } @Provides @Singleton ProductDetailsRepository provideProductDetailsRepository(ProductDetailsRepository repository) { return repository; } }

Mi AppComponent :

@Singleton @Component(modules = {AndroidInjectionModule.class, ActivityModule.class, AppModule.class}) public interface AppComponent { @Component.Builder interface Builder { @BindsInstance Builder application(Application application); AppComponent build(); } void inject(MartApplication martApp); }

Mi solicitud :

public class MartApplication extends Application implements HasActivityInjector { @Inject DispatchingAndroidInjector<Activity> dispatchingAndroidInjector; @Override public void onCreate() { super.onCreate(); } @Override public DispatchingAndroidInjector<Activity> activityInjector() { return dispatchingAndroidInjector; } }

En Actividad :

@Inject ViewModelProvider.Factory viewModelFactory; ....... AndroidInjection.inject(activity); // Throwing exception ListViewModel = ViewModelProviders.of(this, viewModelFactory).get(ProductListViewModel.class);

Está lanzando una excepción al inyectar:

java.lang.IllegalArgumentException: No injector factory bound for Class<com.mymart.ui.ProductListActivity>

¿Puede alguien ayudarme a identificar el problema en mi código?

.................................................. .....................

Edit : lo intenté con ContributesAndroidInjector según @azizbekian, pero resultó el siguiente error en la compilación:

error: [dagger.android.AndroidInjector.inject(T)] Found a dependency cycle: com.mymart.repository.ProductListRepository is injected at com.mymart.di.AppModule.provideProductListRepository(repository) com.mymart.repository.ProductListRepository is injected at com.mymart.viewmodel.ProductListViewModel.<init>(productListRepository) com.mymart.viewmodel.ProductListViewModel is injected at com.mymart.di.ViewModelModule.bindProductListViewModel(listViewModel) java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at com.mymart.viewmodel.ProductViewModelFactory.<init>(creators) com.mymart.viewmodel.ProductViewModelFactory is injected at com.mymart.di.ViewModelModule.bindViewModelFactory(factory) android.arch.lifecycle.ViewModelProvider.Factory is injected at com.mymart.ui.ProductListActivity.viewModelFactory com.mymart.ui.ProductListActivity is injected at dagger.android.AndroidInjector.inject(arg0)

Edición 2 Después de todos los cambios, estoy enfrentando de nuevo la excepción

java.lang.RuntimeException: Unable to create application com.kaushik.myredmart.MartApplication: java.lang.IllegalStateException: com.kaushik.myredmart.di.AppModule must be set at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4710) at android.app.ActivityThread.-wrap1(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.IllegalStateException: com.kaushik.myredmart.di.AppModule must be set at com.kaushik.myredmart.di.DaggerAppComponent$Builder.build(DaggerAppComponent.java:180) at com.kaushik.myredmart.di.AppInjector.init(AppInjector.java:30) at com.kaushik.myredmart.MartApplication.onCreate(MartApplication.java:28) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707) at android.app.ActivityThread.-wrap1(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5417)  at java.lang.reflect.Method.invoke(Native Method)


El uso del @contrubutesAndroidInjector requiere un procesador de anotaciones adicional.

Agregue esta línea a su archivo de compilación de Gradle:

annotationProcessor ''com.google.dagger:dagger-android-processor:2.11''