我不熟悉匕首2。我有两个活动,我想使用注入的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);
}
}
}
我的ViewModel模块:
@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();
}
我的活动模块:
@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;
}
}
在活动中:
@Inject
ViewModelProvider.Factory viewModelFactory;
.......
AndroidInjection.inject(activity); // Throwing exception
ListViewModel = ViewModelProviders.of(this, viewModelFactory).get(ProductListViewModel.class);
它正在注入时引发异常:
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)
dagger2错误比dagger1更直接,但它会一个接一个地弹出,具体取决于dagger在编译时首先面临的问题。
您在解决方案中面临的不仅仅是上述错误:
这是因为您在ActivityModule中为dagger提供了活动,而没有添加注释@ContributesAndroidInjector
此注释必须应用于返回具体Android框架类型的模块中的抽象方法。“即活动/片段等。
@Module
public abstract class ActivityModule {
@ContributesAndroidInjector
abstract ProductListActivity contributeProductListActivity();
@ContributesAndroidInjector
abstract ProductDetailsActivity contributeProductDetailsActivity();
}
裁判
如果您的AppModule没有任何默认构造函数,因此Dagger无法创建AppModule的实例。所以创建一个AppModule实例并将其设置为Dagger图。
mComponent = DaggerXComponent.builder()
.appModule(new AppModule(....)) // create appModule instance
.build();
如果模块没有任何用户定义的构造函数,则Dagger将在需要时通过默认构造函数自动创建实例。
找到这个答案
对于此错误:“匕首:IllegalArgumentException:没有绑定到类的注射器工厂”
如果将导航组件用于单个活动,则可以看到此错误。
你应该怎么做?
请检查您的@模块抽象类FragmentProvider{...},因为您需要在其中添加您的片段作为贡献。
@Module
abstract class FragmentProvider {
@ContributesAndroidInjector // <- Do not forget this line.
abstract fun contributeYourNewFragment(): YourNewFragment
}
我想你忘了把ContributesAndroidInjector注释:
@Module
public abstract class ActivityModule {
@ContributesAndroidInjector
abstract ProductListActivity contributeProductListActivity();
@ContributesAndroidInjector
abstract ProductDetailsActivity contributeProductDetailsActivity();
}
并在AppModule
中包含ViewModelModule
:
@Module(includes = ViewModelModule.class)
class AppModule {
...
}
请参阅您编写的代码:
@Provides
@Singleton
ProductListRepository provideProductListRepository(ProductListRepository repository) {
return repository;
}
你期望会发生什么?你在告诉匕首“嘿,匕首,每当我要求你向我提供ProductListRepository
然后使用ProductListRepository
创建(返回)该对象时”。那是行不通的。
您的意图很可能是“嘿,匕首,每当我要求您为我提供ProductListRepository
的实现时,然后使用ProductListRepositoryImpl
创建(返回)该对象”:
@Provides
@Singleton
ProductListRepository provideProductListRepository(ProductListRepositoryImpl repository) {
return repository;
}
可替换为以下内容:
@Binds
@Singleton
abstract ProductListRepository provideProductListRepository(ProductListRepositoryImpl repository);
我正在使用Dagger 2,在为我的类实现测试时,模块中的generate singleton providers存在一些问题。 所以我有两个问题。 > 我不能使用构造函数注入,因为有一个默认的构造函数。如何从测试模块中获取Foo? 在和中,如何确保在运行每个测试时创建的新实例? 谢谢
问题内容: 我正在尝试将要构建的项目转换为将dagger-android API用于DI框架,但是在尝试使用@ContributesAnroidInjector注入片段时,我遇到了IllegalArgumentException的死胡同。 相关模块和组件如下: ApplicationComponent.java 我的 ActivityBindingModule.java : MainActivit
我目前正在尝试将匕首2集成到一个Android应用程序中。我的项目设置如下: 库 应用程序(取决于库) 在我的library项目中,我定义了一个类,以后我将把它注入到库和app项目中需要它的其他类(活动和常规类)中。 我也是这么想的,因为实际上myManager总是空的。很明显,它的构造函数也从来没有被调用过,所以我想我一定遗漏了一些配置方面的东西?或者也许我误解了文档,它根本不是这样工作的?My
泽西正常使用HK2依赖注入,但我想用匕首2的泽西。Dagger和HK2都实现了JSR330,我认为这是不需要太多努力就可以实现的。我找到了让Jersey与CDI(例如Weld)、Spring DI和Guice一起工作的方法,但在Dagger上我找不到任何东西。 为了提供一些上下文:我正在SE环境中运行Grizzly-Jersey服务器,而不是在EE容器中。我的Maven项目有和作为依赖项,但没有,
我正在尝试为我的navControl ler提供匕首柄。但是我使用的方法不起作用。我想提供navControl ler以便通过构造函数注入将其注入我的片段中。 我还创建了FragmentWorks类,以便通过构造函数注入我的依赖项。我知道是这里的问题,但我不知道正确的解决方案… 感谢您的帮助,谢谢! 原因:java.lang.ClassCastException:com.example.app。应
在一个android、kotlin项目中,看到这个< code>@set:Inject,但找不到一个好的解释。有人知道吗?