Android Dagger 2子组件和依赖组件的问题

Android Dagger 2子组件和依赖组件的问题,android,dagger-2,Android,Dagger 2,我正在研究Dagger 2,遇到了依赖注入问题。我会给你一个关于这个问题的想法。我有一个ApplicationComponent,如下所示 @Singleton @Component(modules = {AppModule.class, MySubComponent.class}) public interface ApplicationComponent { void inject(Application app); List<Integer> pattern;

我正在研究Dagger 2,遇到了依赖注入问题。我会给你一个关于这个问题的想法。我有一个ApplicationComponent,如下所示

@Singleton
@Component(modules = {AppModule.class, MySubComponent.class})
public interface ApplicationComponent {
   void inject(Application app);
   List<Integer> pattern;
   MySubComponent subcomponent();
}
这就是我创建应用程序组件实例的方式

这是子组件

@Singleton
@Subcomponent(modules = MySubModule.class)
public interface MySubComponent {
   void inject(AClass obj);

   INeedThis ineedthis(); 
}

@Module
public class MySubComponent {
   @Provides
   @Singleton
   INeedThis provideINeedThis() {
      return new INeedThis();
   }
}
然后,我创建了另一个组件LoginComponent,并将ApplicationComponent作为依赖项

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity{}

@PerActivity
@Component(dependencies = ApplicationComponent.class, modules = LoginModule.class)
public interface LoginComponent {
    void inject(FirstActivity activity);
}
我创建了LoginComponent实例,如下所示

LoginComponent comp = DaggerLoginComponent.builder().loginModule(new LoginModule().applicationComponent(appComponentObject).build(); 
当我在FirstActivity中注入INeedThis对象时,问题就发生了。我的假设是,由于LoginComponent依赖于ApplicationComponent,ApplicationComponent有一个子组件MySubComponent,因此应该注入该对象。但实际上,它没有做到这一点,我得到以下错误

INeedThis cannot be provided without an @Provides- or @Produces- annotated methods.

我读了很多关于dagger 2子组件的帖子。然而,它们并没有像预期的那样工作。有什么我遗漏的吗?

首先,您没有在上面的代码中使用子组件,这个问题与它们无关,但这是另一个问题

您的
LoginComponent
取决于
ApplicationComponent
,如下所述:

@Component(dependencies = ApplicationComponent.class, modules = LoginModule.class)
public interface LoginComponent {}
这意味着使用
LoginComponent
可以注入
LoginComponent
所知道的一切。这是
LoginModule
提供的所有内容,可以通过构造函数注入*创建的对象,以及
应用程序组件中的公开的对象

如果没有@Provides-或@products-注释的方法,则无法提供此项

也就是说,对于
ined,这些都不是真的

@Component(modules = {AppModule.class, MySubComponent.class})
我不知道如何/为什么将组件添加为模块。如果这是一个输入错误,并且您将
MySubModule
添加到您的组件中,那么您只需添加以下内容即可在该组件中公开

@Component(modules = {AppModule.class, MySubModule.class})
public interface ApplicationComponent {
    //...
    INeedThis getINeedThis();
}

如果这不是输入错误,并且您确实想要使用子组件,那么您的
LoginComponent
应该取决于实际的子组件,但是一旦您修复代码以实际使用子组件,它将以相同的方式工作

根据上面的子组件定义,您可以将应用程序组件更改为不将该组件作为模块列出,并添加一个方法来扩展
应用程序组件

@Singleton
@Component(modules = {AppModule.class}) // removed from modules
public interface ApplicationComponent {
   void inject(Application app);
   List<Integer> pattern;
   MySubComponent subcomponent(); // this will create your subcomponent

   // same as above
   // MySubComponent subcomponent(MySubModule module); use this if you also need to setup your module
}
然后,如果您更改
LoginComponent
,如下所示:

AppComponent appComponent = DaggerAppcomponent.create();
MySubComponent subComponent = appComponent.subcomponent(); // call the method  on your app component
@Component(dependencies = MySubComponent.class, modules = LoginModule.class)
public interface LoginComponent { /**/ }
然后您可以像这样创建它

DaggerLoginComponent.builder().loginModule(new LoginModule().mySubComponent(subComponent).build();

与上面相同,您必须将
getinedthis()
添加到
MySubComponent
接口,以将对象暴露到子图中。

首先,您在上面的代码中没有使用子组件,这个问题与它们无关,但这是另一个问题

您的
LoginComponent
取决于
ApplicationComponent
,如下所述:

@Component(dependencies = ApplicationComponent.class, modules = LoginModule.class)
public interface LoginComponent {}
这意味着使用
LoginComponent
可以注入
LoginComponent
所知道的一切。这是
LoginModule
提供的所有内容,可以通过构造函数注入*创建的对象,以及
应用程序组件中的公开的对象

如果没有@Provides-或@products-注释的方法,则无法提供此项

也就是说,对于
ined,这些都不是真的

@Component(modules = {AppModule.class, MySubComponent.class})
我不知道如何/为什么将组件添加为模块。如果这是一个输入错误,并且您将
MySubModule
添加到您的组件中,那么您只需添加以下内容即可在该组件中公开

@Component(modules = {AppModule.class, MySubModule.class})
public interface ApplicationComponent {
    //...
    INeedThis getINeedThis();
}

如果这不是输入错误,并且您确实想要使用子组件,那么您的
LoginComponent
应该取决于实际的子组件,但是一旦您修复代码以实际使用子组件,它将以相同的方式工作

根据上面的子组件定义,您可以将应用程序组件更改为不将该组件作为模块列出,并添加一个方法来扩展
应用程序组件

@Singleton
@Component(modules = {AppModule.class}) // removed from modules
public interface ApplicationComponent {
   void inject(Application app);
   List<Integer> pattern;
   MySubComponent subcomponent(); // this will create your subcomponent

   // same as above
   // MySubComponent subcomponent(MySubModule module); use this if you also need to setup your module
}
然后,如果您更改
LoginComponent
,如下所示:

AppComponent appComponent = DaggerAppcomponent.create();
MySubComponent subComponent = appComponent.subcomponent(); // call the method  on your app component
@Component(dependencies = MySubComponent.class, modules = LoginModule.class)
public interface LoginComponent { /**/ }
然后您可以像这样创建它

DaggerLoginComponent.builder().loginModule(new LoginModule().mySubComponent(subComponent).build();

与上面相同,您必须将
getinedthis()
添加到
MySubComponent
界面,以将对象暴露到子图中。

设置子组件的想法很难理解。你能告诉我如何设置子组件吗?基本上,我需要一个带有子组件的ApplicationComponent。将ApplicationComponent作为依赖项的所有其他组件都应有权访问子组件。如果这不是标准,请纠正我@Renjith请记住,本网站是针对特定的编程问题,而不是一般的编码信息。您需要如何或为什么使用子组件取决于您试图实现的目标,我无法为您回答这个问题。我已经更新了答案,如果你还需要更多信息,你应该找一些实际的教程,自己试试。谢谢你编辑的答案!我确实试着把它整合到我的应用程序中,但没有成功。也许,我的目标可能略有不同。然而,我深入挖掘了一些github示例,并使其发挥作用。设置子组件的想法很难理解。您能告诉我如何设置子组件吗?基本上,我需要一个带有子组件的ApplicationComponent。将ApplicationComponent作为依赖项的所有其他组件都应有权访问子组件。如果这不是标准,请纠正我@Renjith请记住,本网站是针对特定的编程问题,而不是一般的编码信息。您需要如何或为什么使用子组件取决于您试图实现的目标,我无法为您回答这个问题。我已经更新了答案,如果你还需要更多信息,你应该找一些实际的教程,自己试试。谢谢你编辑的答案!我确实试着把它整合到我的应用程序中,但没有成功。也许,我的目标可能是