我面临的问题是有关在单个Activity中使用App级别和Activity级别的依赖关系。 假设我具有APP级别的依赖项:
@Module
public class FormatModule {
@Provides
@Singleton
public DecimalFormat getDecimalFormat(){
DecimalFormat df = new DecimalFormat("0,000.00");
return df;
}
public class App extends Application {
private static AppComponent AppComponent;
public static AppComponent getAppComponent() {
return AppComponent;
}
@Override
public void onCreate () {
super.onCreate();
AppComponent = DaggerAppComponent
.builder()
.apiModule(new ApiModule())
.build();
}
}
,组件标有@Singleton。
存在活动级别依赖性:
@Module
public class MainActivityModule {
@Provides
Presenter getPresenter(){
return new Presenter();
}
@Component(modules = {MainActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
在MainActivity中,我使用以下代码初始化组件:
MainActivityComponent mainActivityComponent =
DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule())
.contextModule(new ContextModule(this))
.build();
mainActivityComponent.inject(this);
以及在使用ony应用程序级别依赖项的类中:
App.getAppComponent().inject(this);
问题是如何在MainActivity中同时使用App和Activity级别的依赖关系?
答案 0 :(得分:0)
要执行此操作,您需要在MainActivityComponent和AppComponent之间建立一个component dependency。
@Component(
modules = {MainActivityModule.class},
dependencies = {AppComponent.class}) // <-- this
public interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
这告诉Dagger,它可以在AppComponent上调用零参数方法来提供MainActivityComponent所需的依赖关系,包括MainActivity注入的对象的依赖关系。这使得它特别适合依赖于其他Dagger组件,因为您可以将这些零参数方法添加到AppComponent上,并且Dagger将提供实现。但是,为了清楚起见或避免依赖周期,您可能还选择列出 interface 作为依赖项,然后提供DaggerAppComponent实现。
您需要提供AppComponent的实现作为ActivityComponent构建器的一部分:
MainActivityComponent mainActivityComponent =
DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule())
.contextModule(new ContextModule(this))
.appComponent(App.getAppComponent()) // <-- this
.build();
mainActivityComponent.inject(this);
重要:在MainActivityComponent中,您唯一可用的绑定是在您列出为依赖项的接口或类上作为零参数方法公开的绑定 (“设置方法”)。如果您在AppComponent模块上使用@Provides
方法提供绑定,除非您在AppComponent本身上为其添加了一个吸气剂,否则它将不会出现在MainActivityComponent 中。这使您可以具体说明从AppComponent继承的内容,但可以视为维护负担。
@Component(modules = ModuleA.class) public interface ComponentA {
BindingOne bindingOne();
}
@Module public abstract class ModuleA {
@Provides static BindingOne getBindingOne() { return BindingOne.INSTANCE; }
@Provides static BindingTwo getBindingTwo() { return BindingTwo.INSTANCE; }
}
// ComponentB has access to BindingOne but not BindingTwo, because it can only see
// what is available in ComponentA, not ComponentA's module set that includes ModuleA.
@Component(dependencies = ComponentA.class) public interface ComponentB { /* ... *}
getDecimalFormat
和getPresenter
不使用任何实例状态,因此可以将它们设置为static
; Dagger将检测到此情况并进行静态调用,而不是slightly slower on Android的虚拟方法调用。如果将所有@Module方法切换为static @Provides
或abstract @Binds
方法,则可以将Module更改为接口或抽象类,这意味着Dagger可以并且将完全跳过实例化该方法。 / li>