我正在尝试学习Dagger2。就在我以为我明白了的时候,我似乎卡住了。我的应用程序有两个组件,应用程序组件(单例(和条带组件(1:1 活动(,为了可读性,它们继承了一个空接口。
然后它有两个模块,ApplicationModule 和 StripeModule。
@Singleton @Component(modules = ApplicationModule.class)
public interface ApplicationComponent extends AbstractComponent ...
@PerActivity @Component(modules = { StripeModule.class }) public interface StripeComponent
extends AbstractComponent ...
@Module public class ApplicationModule
@Module public class StripeModule
ApplicationModule 提供的对象之一是导航器,我相当确定它的方式相当正确:
@Provides @Singleton Navigator provideNavigator() {
return new Navigator();
}
这是一个非常简单的类,其中几乎没有任何东西:
@Singleton public class Navigator
然后,当我生成代码时,会从 StripeModule - StripeModule_ProvideNavigatorFactory 生成一个额外的供应工厂。然后编译器抱怨我没有提供它 - 这是真的,也是故意的。它应仅由应用程序组件提供。问题是,为什么要生产这个工厂呢?为什么 Dagger2 不明白 StripeModule 不应该提供导航器?
假设你有一个使用 StripeComponent
注入自身的 StripeActivity
类,那么你最终可能会得到这样的场景
public class StripeActivity extends AppCompatActivity {
@Inject
Navigator navigator;
@Override
public void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
CustomApplication application = (CustomApplication)getApplicationContext();
StripeComponent stripeComponent = createComponent(application);
stripeComponent.inject(this);
}
protected StripeComponent createComponent(CustomApplication application) {
return DaggerStripeComponent.builder()
.applicationComponent(application.getApplicationComponent())
.build();
}
}
public class CustomApplication extends Application {
ApplicationComponent applicationComponent;
@Override
protected void onCreate() {
super.onCreate();
applicationComponent = createApplicationComponent();
}
protected ApplicationComponent createApplicationComponent() {
return DaggerApplicationComponent.create();
}
public ApplicationComponent getApplicationComponent() {
return applicationComponent;
}
}
@Component(modules={ApplicationModule.class})
@Singleton
public interface ApplicationComponent {
Navigator navigator();
}
@Component(dependencies={ApplicationComponent.class}, modules={StripeModule.class})
@PerActivity
public interface StripeComponent extends ApplicationComponent {
void inject(StripeActivity stripeActivity);
}
@Module
public class ApplicationModule {
@Provides
@Singleton
Navigator navigator() {
return new Navigator();
}
}
@Module
public class StripeModule {
//@Provides
//@PerActivity
//...
}
@Scope
@Retention(RUNTIME)
public @interface PerActivity {
}
编辑:对于基类注入,您需要手动注入超类和子类,并且需要在组件中指定超类和子类。在这种情况下,它将像这样工作。
public abstract class BaseActivity extends AppCompatActivity {
@Inject
Navigator navigator;
@Override
public void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
CustomApplication application = (CustomApplication)getApplicationContext();
ApplicationComponent component = createComponentAndInjectSelf(application);
component.inject(this);
}
protected abstract ApplicationComponent createComponentAndInjectSelf(CustomApplication application);
}
public class StripeActivity extends BaseActivity {
@Override
public void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
}
@Override
public StripeComponent createComponentAndInjectSelf(CustomApplication application) {
StripeComponent stripeComponent = DaggerStripeComponent.builder()
.applicationComponent(application.getApplicationComponent())
.build();
stripeComponent.inject(this);
return stripeComponent;
}
}
@Component(modules={ApplicationModule.class})
@Singleton
public interface ApplicationComponent {
Navigator navigator();
void inject(BaseActivity baseActivity);
}
@Component(dependencies={ApplicationComponent.class}, modules={StripeModule.class})
@PerActivity
public interface StripeComponent extends ApplicationComponent {
void inject(StripeActivity stripeActivity);
}
您尚未包含确切的错误或实际取决于Navigator
的代码。
但是我会假设依赖于Navigator
的类是从StripeModule
或安装在StripeComponent
中的另一个模块提供的。
StripeComponent
和 ApplicationComponent
必须以某种方式相关,以便 StripeComponent
中的绑定使用 ApplicationComponent
提供的绑定。
您可以使用组件依赖项或子组件来关联它们。
如果你使用子组件,你会StripeComponent
ApplicationComponent
的子组件,这意味着它可以使用安装在ApplicationComponent
模块中的任何绑定,包括用于Navigator
的绑定。
如果要使用组件依赖项,则需要使StripeComponent
依赖于ApplicationComponent
,并且要添加一个方法Navigator navigator()
ApplicationComponent
。StripeComponent
中的绑定可以依赖于它所依赖的组件上的方法返回的任何类型。