在阅读了@vaughandroid 的答案后,什么决定了 Dagger 2 中组件(对象图)的生命周期?我认为我对自定义范围的了解足以回答我自己的问题。
首先,在处理 dagger2 中的组件、模块和作用域注释时,这里有一些规则。
- 一个组件 必须有一个(单一的)范围注释(例如
@Singleton
or @CustomScope
)。
- 模块 没有范围注释。
- 一个模块方法 可能有一个(单个)范围与它的组件匹配或没有范围,其中:
- Scoped:表示为组件的每个实例创建一个实例。
- Unscoped:意味着每次注入()或提供程序调用都会创建一个新实例
- 注意: Dagger2 仅为
@Singleton
根组件(及其模块)保留。子组件必须使用自定义范围,但该范围的功能与@Singleton
.
现在,回答这个问题:我想说为每个概念上不同的范围创建一个新的命名范围。例如,创建一个@PerActivity
、@PerFragment
或@PerView
注释,指示组件应在何处实例化,从而指示其生命周期。
注意:这是两个极端之间的折衷。考虑您需要的根组件和n个子组件的情况:
- 至少2 个注释(
@Singleton
和@SubSingleton
),以及
- 最多 n+1 个注释(
@Singleton
,@SubSingleton1
, ...@SubSingletonN
)。
例子:
应用:
/** AppComponent.java **/
@Singleton
@Component( modules = AppModule.class )
public interface AppComponent{
void inject(MainActivity mainActivity);
}
/** AppModule.java **/
@Module
public class AppModule{
private App app;
public AppModule(App app){
this.app = app;
}
// For singleton objects, annotate with same scope as component, i.e. @Singleton
@Provides @Singleton public App provideApp() { return app; }
@Provides @Singleton public EventBus provideBus() { return EventBus.getDefault(); }
}
分段:
/** Fragment1Component.java **/
@PerFragment
@Component( modules = {Fragment1Module.class}, dependencies = {AppComponent.class} )
public interface Fragment1Component {
void inject(Fragment1 fragment1);
}
/** Fragment1Module.java **/
@Module
public class Fragment1Module {
// For singleton objects, annotate with same scope as component, i.e. @PerFragment
@Provides @PerFragment public Fragment1Presenter providePresenter(){
return new Fragment1Presenter();
}
}
/** PerFragment.java **/
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerFragment {}