Scope
中文意思是范圍,Dagger2 中的@Singleton
是 Scope 的一種默認(rèn)實現(xiàn)奕扣,點進去可以看到:
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
上面是 Java 方式,如果我們自定義一個 Scope 就很簡單了(kotlin 語言):
@Documented
@Scope
@Retention(RetentionPolicy.RUNTIME)
annotation class ZhuangBiScope
一個 Component 依賴另一個 Component 時需要用到 Scope惯豆,至于為什么 Component 之間要互相依賴,簡單說下:一個項目里有很多功能模塊楷兽,很多的 Activity,每個 Activity 都有對應(yīng)的 Component芯杀,那么每個 Component 再對應(yīng)多個 Module,最終工程會很龐大揭厚。有些 Module 可以共用,所以就需要dependencies
關(guān)鍵字來依賴別的 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)
結(jié)果總是報錯鞭莽,在這里卡了很久。需要說明的是:
當(dāng)一個 Component 給別的 Component 依賴時澎怒,被依賴的 Component 要定義一些方法。這些方法的返回值類型和它包含的 Module 中方法返回類型相同阶牍。
舉例說明,BComponent 包含 PersonModule 和 StudentModule走孽,兩者分別包含:
@Singleton
@Provides
fun providePerson(): Person = Person()
@Provides
fun provideStudent(): Student = Student()
當(dāng) AnimalComponent 所 inject 的類中需要用到上面這兩個實例的時候,就需要在 BComponent 中注冊兩個方法給 inject 的類使用(方法名叫什么都無所謂):
fun person(): Person
fun provideStudent(): Student
另外磕瓷,BComponent 中不可以定義其他方法,否則也會報錯困食。