我关注这个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 {
}
这是我的登录 Activity :
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
注解上。我们为什么要再次复制。- 如何在上述 Activity 中注入(inject) LoginPresenter。
谢谢
最佳答案
@Subcomponent.Builder遵循 @Component.Builder 中记录的相同规则:您需要为 Dagger 无法自行初始化的每个模块设置一个 setter。 (允许模块具有构造函数参数或静态工厂方法,这将阻止 Dagger 创建自己的实例。)
因为 Dagger 可以通过调用零参数构造函数来创建 LoginModule,所以您可以从 Builder 中删除该方法;你不需要重新创建它。您也可以考虑制作 LoginModule 的方法
static
,这将允许您使 LoginModule 成为一个接口(interface)或抽象类——然后 Dagger 将能够完全避免持有对该模块的引用。最后,对于简单的@Provides
绑定(bind)两个类的方法(例如@Provides B provideB(A a) { return a; }
)你可以切换到@Binds
,这将使生成的代码更快。那时,您的
@Subcomponent.Builder
成为特定于子组件的Provider
: 你可以注入(inject)你的Builder
或Provider<Builder>
并通过调用build()
获取一个新的子组件实例在上面。只要您不需要提供任何 Module 实例,您就不需要在构建器上使用任何其他方法。您可以简单地注入(inject)一个
Provider<LoginComponent>
,但我没有在实践中看到过,也没有自己尝试过。要注入(inject)一个 LoginPresenter,您需要获取您的 AppComponent,创建一个新的 LoginComponent,并通过传入它来使用它来注入(inject)您的 Activity。但是,这可能很困难,因为您还没有给自己任何注入(inject)您的 LoginComponent.Builder 的权限。
除非你想尝试 dagger.android相反,您可以添加一个方法来调用您的 AppComponent 以创建一个新的 LoginComponent。
// This way... LoginComponent createLoginComponent(); // or this way: LoginComponent.Builder createLoginComponentBuilder();
有时您会看到名为
plus()
的第一个方法,这是 Dagger 1 中建立的命名约定;第一种方法还可以让您避免创建 @Subcomponent.Builder 或在AppModule
中添加子组件。 ,尽管您可能希望保留现有结构的结构,以便稍后向您的 AppModule 添加更多内容。要完成它,请在
Activity.onCreate
中,您可以让您的 Activity 获取您的应用程序,访问其 AppComponent,并注入(inject)自身。((YourApplication) getContext().getApplicationContext()) .getApp() .createLoginComponent() .inject(this);
关于android - Dagger 2 : inject after define subcomponent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43214994/