我按照此guide为我的Android应用程序制作子组件。在这里,我定义了一个名为LoginComponent
的子组件,用于LoginActivity:
@Subcomponent(modules = LoginModule.class)
public interface LoginComponent {
void inject(LoginActivity activity);
@Subcomponent.Builder
interface Builder {
Builder requestModule(LoginModule module);
LoginComponent build();
}
}
@Module
public class LoginModule {
@Provides
LoginManager provideLoginManager(LoginManagerImpl manager) {
return manager;
}
@Provides
LoginView provideLoginView(LoginViewImpl view) {
return view;
}
@Provides
LoginPresenter loginPresenter(LoginView view, LoginManager manager) {
return new LoginPresenterImpl(view, manager);
}
}
我在另一个组件中定义了这个子组件:
@Module(subcomponents = LoginComponent.class)
public interface AppModule {
}
@Singleton
@Component(modules = {
AppModule.class
})
public interface AppComponent {
}
这是我的LoginActivity:
public class LoginActivity extends AppCompatActivity {
@Inject LoginPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}
}
我的问题是:
@Subcomponent.Builder
的目的。我不明白这一点,因为此组件中的所有模块都已在@Subcomponent
注释中定义。我们为什么要重复一次。由于
答案 0 :(得分:3)
@Subcomponent.Builder遵循@Component.Builder中记录的相同规则:您需要为Dagger无法初始化的每个模块设置一个setter。 (允许模块具有构造函数参数或静态工厂方法,这会阻止Dagger创建自己的实例。)
因为Dagger可以通过调用零参数构造函数来创建一个LoginModule,所以可以从Builder中删除该方法;你不需要重新创建它。您也可以考虑使用LoginModule的方法static
,这将允许您使LoginModule成为接口或抽象类 - 然后Dagger将能够避免持有对模块的引用。最后,对于绑定两个类的简单@Provides
方法(例如@Provides B provideB(A a) { return a; }
),您可以切换到@Binds
,这样可以使生成的代码更快。
此时,您的@Subcomponent.Builder
成为特定于子组件的Provider
:您可以注入Builder
或Provider<Builder>
并通过调用{{{{}}来获取新的子组件实例1}}就可以了。只要您不需要提供任何模块实例,您就不需要在构建器上使用任何其他方法。
你可以简单地注射一个build()
,但我在实践中没有看到它,并且我自己没有尝试过。
要注入LoginPresenter,您需要访问AppComponent,创建一个新的LoginComponent,并通过传入它来使用它注入您的Activity。但是,这可能很难,因为您还没有给自己任何注入LoginComponent.Builder的权限。
除非您想尝试使用dagger.android,否则可以添加一个方法来调用AppComponent来创建新的LoginComponent。
Provider<LoginComponent>
有时您会看到名为// This way...
LoginComponent createLoginComponent();
// or this way:
LoginComponent.Builder createLoginComponentBuilder();
的第一种方式,这是在Dagger 1中建立的命名约定;第一种方法还可以避免创建@ Subcomponent.Builder或在plus()
中添加子组件,尽管您可能希望以您拥有它的方式保留结构,以便稍后可以向AppModule添加更多。
要完成它,在AppModule
中,您可以让您的活动获取您的应用程序,访问其AppComponent并注入自己。
Activity.onCreate