gpt4 book ai didi

android - Dagger :IllegalArgumentException:没有注入(inject)器工厂绑定(bind)到类

转载 作者:IT王子 更新时间:2023-10-29 00:04:04 26 4
gpt4 key购买 nike

我是 Dagger 2 的新手。我有 2 个 Activity ,我想对两者都使用注入(inject)的 ViewModel。这是我的 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);
}
}
}

我的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);
}

我的 ViewModelKey 用于映射:

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

我的ActivityModule:

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

我的AppModule:

@Module
class AppModule {

@Provides
@Singleton
RedMartProductService provideRedMartProductService() {
........
}

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

@Provides
@Singleton
ProductDetailsRepository provideProductDetailsRepository(ProductDetailsRepository repository) {
return repository;
}
}

我的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);
}

我的应用程序:

public class MartApplication extends Application implements HasActivityInjector {

@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

@Override
public void onCreate() {
super.onCreate();
}

@Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}

Activity 中:

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

在注入(inject)时抛出异常:

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

谁能帮我找出代码中的问题?

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

编辑:我按照@azizbekian 尝试使用 ContributesAndroidInjector,但在构建时出现以下错误:

    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)

编辑 2经过所有更改,我再次面临异常:

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)

最佳答案

相信你忘了放@ContributesAndroidInjector注解:


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

And include ViewModelModule within AppModule:


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

See this code that you have wrote:

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

你期望会发生什么?你是在告诉 dagger “嘿,dagger,每当我要求你提供 ProductListRepository 然后使用 ProductListRepository 创建(返回)该对象。那是行不通的。

您最可能想要的是“嘿, Dagger ,每当我要求您提供 ProductListRepository 的实现时,然后使用 ProductListRepositoryImpl 创建(返回)该对象>":

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

可以用以下代替:

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

关于android - Dagger :IllegalArgumentException:没有注入(inject)器工厂绑定(bind)到类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45326775/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com