Scope
中文意思是范围,Dagger2 中的@Singleton
是 Scope 的一种默认实现,点进去可以看到:
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
上面是 Java 方式,如果我们自定义一个 Scope 就很简单了(kotlin 语言):
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
annotation class ZhuangBiScope
一个 Component 依赖另一个 Component 时需要用到 Scope,至于为什么 Component 之间要互相依赖,简单说下:一个项目里有很多功能模块,很多的 Activity,每个 Activity 都有对应的 Component,那么每个 Component 再对应多个 Module,最终工程会很庞大。有些 Module 可以共用,所以就需要dependencies
关键字来依赖别的 Component。
比如 AnimalComponent 要依赖 BComponent
AnimalComponent.kt
@ZhuangBiScope
@Component(dependencies = [(BComponent::class)],modules = [(AppModule::class), (AnimalModule::class)])
interface AnimalComponent {
fun inject(secondActivity: SecondActivity)
}
AnimalComponent 需要依赖 BComponent,则@ZhuangBiScope
注解在 AnimalComponent 上面。另外,AnimalComponent 包含的 AppModule 和 AnimalModule 里面的provideXX()
方法要么不用任何 Scope 注解,要么用@ZhuangBiScope
注解,不可以用@Singleton
注解。
AppModule.kt
@Module
class AppModule(var myApp: Application) {
@Provides
@ZhuangBiScope
fun providesApplication(): Application = myApp
}
AnimalModule.kt
@Module
class AnimalModule {
@Provides
@ZhuangBiScope
fun providesDog(): Dog {
Log.e("abc", "----- AnimalModule Dog -----")
return Dog()
}
@Provides
@Tested("dog")
@ZhuangBiScope
fun providesCat(dog: Dog): Cat {
Log.e("abc", "----- AnimalModule Cat withdog -----")
return Cat(dog)
}
@Provides
@Tested("dog2")
fun providesCat2(dog: Dog): Cat {
Log.e("abc", "----- AnimalModule Cat withdog2 -----")
return Cat(dog)
}
}
上面的 providesCat2() 方法没有任何 Scope 注解。
接下来我们看看 BComponent:
@Singleton
@Component(modules = [(PersonModule::class), (StudentModule::class)])
interface BComponent {
fun inject(bActivity: BActivity)
fun person(): Person
fun provideStudent(): Student
// fun test(): String//会报错
}
包含两个 Module,一开始我只写了第一行的fun inject(bActivity: BActivity)
结果总是报错,在这里卡了很久。需要说明的是:
当一个 Component 给别的 Component 依赖时,被依赖的 Component 要定义一些方法。这些方法的返回值类型和它包含的 Module 中方法返回类型相同。
举例说明,BComponent 包含 PersonModule 和 StudentModule,两者分别包含:
@Singleton
@Provides
fun providePerson(): Person = Person()
@Provides
fun provideStudent(): Student = Student()
当 AnimalComponent 所 inject 的类中需要用到上面这两个实例的时候,就需要在 BComponent 中注册两个方法给 inject 的类使用(方法名叫什么都无所谓):
fun person(): Person
fun provideStudent(): Student
另外,BComponent 中不可以定义其他方法,否则也会报错。