使用依賴注入的好處在這里不細(xì)說,我們重點(diǎn)了解如何在Android項(xiàng)目中使用dagger2
1. 引入dagger2
implementation 'com.google.dagger:dagger-android:2.25.2'
implementation 'com.google.dagger:dagger-android-support:2.25.2'
// if you use the support libraries
implementation 'com.google.dagger:dagger:2.25.2'
kapt 'com.google.dagger:dagger-compiler:2.25.2'
kapt 'com.google.dagger:dagger-android-processor:2.25.2'
注意如果項(xiàng)目級(jí)別的gradle文件中沒有
apply plugin: 'kotlin-kapt'
要記得加上,不然會(huì)報(bào)錯(cuò)
2.聲明提供方
我們可以在一個(gè)類的構(gòu)造方法上加上@Inject來表明當(dāng)有一個(gè)類使用到我們這個(gè)類的實(shí)例的時(shí)候,可以調(diào)用我們這個(gè)用注解標(biāo)記的構(gòu)造方法來生成一個(gè)
class Model constructor(
val uuid: String
) {
@Inject
constructor() : this(UUID.randomUUID().toString())
}
3.聲明使用方
在需要提供注入的類的屬性上使用@Inject來表明我們這個(gè)屬性需要dagger2來注入
class MainActivity : AppCompatActivity() {
@Inject
lateinit var model1: Model
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
4.聲明注入器
現(xiàn)在我們有了依賴的提供方和依賴的使用方,那么如何把這兩者結(jié)合起來,讓依賴注入到使用者需要的屬性上呢?我們這里就需要用到@Component注解來生成一個(gè)注解器。
我們用@Component來注解一個(gè)接口,dagger2會(huì)在編譯時(shí)自動(dòng)生成一個(gè)Dagger+類名的實(shí)現(xiàn)類實(shí)現(xiàn)依賴注入。具體使用方法有以下兩種:
- Members-injection methods
該方法有一個(gè)參數(shù),這個(gè)參數(shù)表示需要注入的對(duì)象,告知dagger2去尋找需要的依賴并注入到對(duì)象的屬性上,例如
@Component
interface MainComponent {
fun inject(mainActivity: MainActivity)
}
- Provision methods
聲明一個(gè)不需要參數(shù)但有返回值的方法,返回一個(gè)需要被注入的依賴,返回對(duì)象由使用者自行處理,例如:
@Component
interface SecondComponent {
fun getModel(): Model
}
5.使用注入器注入依賴
當(dāng)我們聲明了依賴的提供方、依賴的使用方和注入器,我們就可以使用依賴注入了。編譯項(xiàng)目,會(huì)生成Dagger+注入器為類名的注入器的實(shí)現(xiàn)類。
class MainActivity : AppCompatActivity() {
@Inject
lateinit var model1: Model
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
DaggerMainComponent.builder().build().inject(this)
model1.uuid.log()
}
}
在注入器注入依賴后,我們就可以使用被注入的對(duì)象了。
6.第三方依賴注入
我們可以使用@Inject來標(biāo)識(shí)一個(gè)構(gòu)造函數(shù),當(dāng)我們需要這個(gè)類的實(shí)例時(shí),我們會(huì)調(diào)用@Inject標(biāo)識(shí)的構(gòu)造方法來創(chuàng)建一個(gè)對(duì)象。但是如果我們需要注入的是一個(gè)第三方的對(duì)象,我們沒有辦法去修改第三方的源碼,我們應(yīng)該怎么辦?
我們可以使用@Module和@Provides來搭配使用:
- 新建一個(gè)module接口,在接口上使用@Module
- 聲明一個(gè)方法, 返回值為我們需要的類型
@Module
class HttpServiceModule {
@Provides
fun provideHttpService(): HttpService {
return HttpService()
}
}
- 在注入器的@Component里面添加我們剛才新建的module
@Component(modules = [HttpServiceModule::class])
interface HttpComponent {
fun inject(httpActivity: HttpActivity)
}
然后就可以正常使用了
7.指定依賴注入
有時(shí)我們會(huì)遇到這么一種情況,我們會(huì)提供同一個(gè)類型的不同的依賴,比如我們項(xiàng)目中集成了高德地圖和百度地圖,我把兩個(gè)地圖的key使用依賴注入的方式來注入到初始化的代碼中,在一個(gè)module里面聲明了兩個(gè)類型都是字符串的key,如何讓dagger2知道我們需要的是哪一個(gè)呢?
class KeyActivity : AppCompatActivity() {
@Inject
lateinit var key: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_key)
}
}
@Module
class KeyModule {
@Provides
fun provideAmapKey(): String = "amap"
@Provides
fun provideBaiduKey(): String = "baidu"
}
@Component(modules = [KeyModule::class])
interface KeyComponent {
fun inject(keyActivity: KeyActivity)
}
我們可以使用@Named注解,在注解提供的方法上和需要注入的屬性上使用相同的字符串,通過字符串匹配,讓dagger2知道我們要的是哪個(gè)。例如:
class KeyActivity : AppCompatActivity() {
@Named("amap")
@Inject
lateinit var key: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_key)
DaggerKeyComponent.create().inject(this)
key.log()
}
}
@Module
class KeyModule {
@Named("amap")
@Provides
fun provideAmapKey(): String = "amap"
@Named("baidu")
@Provides
fun provideBaiduKey(): String = "baidu"
}
@Component(modules = [KeyModule::class])
interface KeyComponent {
fun inject(keyActivity: KeyActivity)
}
當(dāng)然有些人覺得用字符串來標(biāo)識(shí)指定注解不太靠譜,因?yàn)樽址赡軙?huì)寫錯(cuò)。我們可以使用@Qualifier注解來標(biāo)識(shí)我們自己創(chuàng)建的注解,當(dāng)提供方的自定義注解和使用方的自定義注解相同時(shí),dagger2就會(huì)為我們做出正確的注入。
class Dog : Animal {
override fun toString(): String {
return "dog"
}
}
class Cat : Animal {
override fun toString(): String {
return "cat"
}
}
@Module
class AnimalModule {
@DogAnimal
@Provides
fun provideDog(): Animal = Dog()
@CatAnimal
@Provides
fun provideCat(): Animal = Cat()
}
@Component(modules = [AnimalModule::class])
interface AnimalComponent {
fun inject(animalActivity: AnimalActivity)
}
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class DogAnimal
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class CatAnimal
class AnimalActivity : AppCompatActivity() {
@CatAnimal
@Inject
lateinit var animal: Animal
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_animal)
DaggerAnimalComponent.create().inject(this)
animal.toString().log()
}
}
8.單例
考慮一下代碼,一個(gè)使用方需要使用兩個(gè)依賴,這兩個(gè)依賴類型一樣,他們會(huì)是同一個(gè)對(duì)象嗎?或者說在注入的時(shí)候會(huì)調(diào)用幾次帶有@Inject的構(gòu)造方法?
class PeopleActivity : AppCompatActivity() {
@Inject
lateinit var people1: People
@Inject
lateinit var people2: People
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_people)
DaggerPeopleComponent.create().inject(this)
"$people1 $people2 ${people1 === people2}".log()
}
}
class People @Inject constructor()
@Component
interface PeopleComponent {
fun inject(peopleActivity: PeopleActivity)
}
考慮下上面的輸入是什么?上面的輸入是
com.ke.dagger2_demo.People@5aa9f47 com.ke.dagger2_demo.People@e17a374 false
但是有些時(shí)候我們不希望每次使用依賴的時(shí)候都去創(chuàng)建一個(gè)對(duì)象,比如使用我們的http client,我們希望全局有且僅有唯一一個(gè)http client,那么這時(shí)我們應(yīng)該怎么做?
我們可以使用@Singleton注解放在我們希望是單例的類名上,告訴dagger2在創(chuàng)建該類實(shí)例的時(shí)候只能創(chuàng)建一次。
@Singleton
class People @Inject constructor()
注意一點(diǎn),在對(duì)應(yīng)的注入器上同樣要加上@Singleton注解
@Singleton
@Component
interface PeopleComponent {
fun inject(peopleActivity: PeopleActivity)
}
晚上上述操作后在看看我們的輸入
com.ke.dagger2_demo.People@5aa9f47 com.ke.dagger2_demo.People@5aa9f47 true
加了@Singleton注解后,兩個(gè)依賴是同一個(gè)對(duì)象,不會(huì)在使用依賴的時(shí)候額外創(chuàng)建了。
額外提一點(diǎn),@Singleton是@Scope的一個(gè)實(shí)現(xiàn),類似@Named和@Qualifier一樣,如果你不喜歡Singleton這個(gè)名字,可以自己創(chuàng)建一個(gè)自定義注解并用@Scope來標(biāo)識(shí)。
9.@Binds
在實(shí)際項(xiàng)目中,我們可能會(huì)遇到這么一種情況,我們需要注入的依賴類型是抽象的,我們可以在指定的module中利用@Provide注解一個(gè)方法,接收一個(gè)實(shí)現(xiàn)類對(duì)象,返回的類型是抽象的,例如:
class WeaponActivity : AppCompatActivity() {
@Inject
lateinit var weapon: Weapon
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_weapon)
DaggerWeaponComponent.create().inject(this)
}
}
interface Weapon {
fun attack()
}
class Gun @Inject constructor() : Weapon {
override fun attack() {
"gun attack".log()
}
}
class Sword @Inject constructor() : Weapon {
override fun attack() {
"sword attack".log()
}
}
@Module
class WeaponModule {
//接收一個(gè)實(shí)現(xiàn)類的對(duì)象,返回抽象類型
@Provides
fun provideWeapon(gun: Gun): Weapon {
return gun
}
}
@Component(modules = [WeaponModule::class])
interface WeaponComponent {
fun inject(weaponActivity: WeaponActivity)
}
我們?cè)谶@里可以用@Binds注解來簡化這一步驟,把module中的方法改為抽象方法,module改為抽象類,然后把方法前綴provide改成bind,@Provide注解修改成@Binds,就可以起到相同的功能。
@Module
abstract class WeaponModule {
@Binds
abstract fun bindWeapon(gun: Gun): Weapon
}
10.注入到Set中
如果我們需要注入的不是單個(gè)對(duì)象,而是一個(gè)集合,例如:
@Inject
lateinit var carSet: Set<Car>
我們應(yīng)該怎么做呢?
我們可以利用@IntoSet方法,把module提供的依賴打包成Set集合注入到我們需要的地方,例如:
class IntoSetActivity : AppCompatActivity() {
@Inject
lateinit var carSet: Set<Car>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_into_set)
DaggerCarComponent.create().inject(this)
carSet.forEach {
it.toString().log()
}
}
}
data class Car(val name: String)
@Module
class CarModule {
@Provides
@IntoSet
fun provideA(): Car {
return Car("A")
}
@Provides
@IntoSet
fun provideB(): Car {
return Car("B")
}
}
@Component(modules = [CarModule::class])
interface CarComponent {
fun inject(intoSetActivity: IntoSetActivity)
}
11.注入到Map中
如果我們需要注入的對(duì)象類型是一個(gè)map,我們也能注入嗎?可以的,和注入到Set類似,我們只需要把@IntoSet修改成@IntoMap,我們就可以,并且需要指定key。代碼如下:
class IntoMapActivity : AppCompatActivity() {
@Inject
lateinit var foodMap: Map<String, Food>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_into_map)
DaggerFoodComponent.create().inject(this)
foodMap.forEach {
"key = ${it.key} , value = ${it.value}".log()
}
}
}
data class Food(val name: String)
@Module
class FoodModule {
@IntoMap
@Provides
@StringKey("apple")
fun provideApple(): Food {
return Food("apple")
}
@IntoMap
@Provides
@StringKey("milk")
fun provideMilk(): Food {
return Food("milk")
}
}
@Component(modules = [FoodModule::class])
interface FoodComponent {
fun inject(intoMapActivity: IntoMapActivity)
}
12.運(yùn)行時(shí)注入
如果一個(gè)提供方的構(gòu)造函數(shù)包含一個(gè)參數(shù),并且這個(gè)參數(shù)的具體的值只有在程序運(yùn)行的時(shí)候才知道,比如;
class RuntimeInjectActivity : AppCompatActivity() {
@Inject
lateinit var bike: Bike
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_runtime_inject)
DaggerBikeComponent.builder().bikeModule(BikeModule(100))
.build().inject(this)
"bike price = ${bike.price}".log()
}
}
data class Bike(val price: Int)
我們需要給activity注入一個(gè)bike對(duì)象,但是bike的價(jià)格只有在運(yùn)行的時(shí)候才知道,我們不能直接在Bike類的構(gòu)造方法上加上@Inject注解,因?yàn)槲覀儧]法提供價(jià)格,我們也不能使用無參數(shù)的Provide方法,因?yàn)閯?chuàng)建Bike對(duì)象必須提供一個(gè)價(jià)格,那么我們?cè)撛趺醋??我們可以在?chuàng)建Module的時(shí)候提供一個(gè)參數(shù),在Provide方法里面把這個(gè)價(jià)格給傳入到Bike的構(gòu)造方法里面,如下:
@Module
class BikeModule(private val price: Int) {
@Provides
fun provideBike(): Bike {
return Bike(price)
}
}
完成例子如下:
class RuntimeInjectActivity : AppCompatActivity() {
@Inject
lateinit var bike: Bike
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_runtime_inject)
DaggerBikeComponent.builder().bikeModule(BikeModule(100))
.build().inject(this)
"bike price = ${bike.price}".log()
}
}
data class Bike(val price: Int)
@Module
class BikeModule(private val price: Int) {
@Provides
fun provideBike(): Bike {
return Bike(price)
}
}
@Component(modules = [BikeModule::class])
interface BikeComponent {
fun inject(runtimeInjectActivity: RuntimeInjectActivity)
}
13.BindsInstance
在正常情況下,如果我們的module里面的某個(gè)Provide方法在創(chuàng)建需要注入的對(duì)象的時(shí)候需要另外一個(gè)對(duì)象,例如下面創(chuàng)建Computer對(duì)象的時(shí)候需要用到Application對(duì)象,我們可以通過構(gòu)造方法來傳入一個(gè)Application對(duì)象,在創(chuàng)建Component對(duì)象的時(shí)候調(diào)用
.computerModule(ComputerModule(application))
來傳入Module。
class BuilderActivity : AppCompatActivity() {
@Inject
lateinit var computer: Computer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_builder)
DaggerComputerComponent
.builder()
.computerModule(ComputerModule(application))
.build().inject(this)
}
}
data class Computer(val name: String)
@Module
class ComputerModule(private val application: Application) {
@Provides
@Singleton
fun provideComputer(): Computer {
return Computer(application.packageName)
}
}
@Singleton
@Component(modules = [ComputerModule::class])
interface ComputerComponent {
fun inject(builderActivity: BuilderActivity)
}
那么我們有別的方式在Module的Provide方法中提供需要的對(duì)象來創(chuàng)建我們要注入的對(duì)象嗎?
有的,我們先改造我們Module里面的Provide方法
@Module
class ComputerModule {
@Provides
@Singleton
fun provideComputer(application: Application): Computer {
return Computer(application.packageName)
}
}
我們可以看到,Application對(duì)象是作為方法參數(shù)傳入到provideComputer方法里面,意味著我們需要提供一個(gè)Application對(duì)象?,F(xiàn)在我們?cè)賮砀脑煳覀兊腃omponent注入器:
@Singleton
@Component(modules = [ComputerModule::class])
interface ComputerComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ComputerComponent
}
fun inject(builderActivity: BuilderActivity)
}
我們通過@Component.Builder注解來標(biāo)識(shí)我們要自己創(chuàng)建Component的構(gòu)造器(Builder),在通過** @BindsInstance**來告訴構(gòu)造器Module需要的Application是通過這個(gè)方法傳入的,那么我們的注入方法就變成了
DaggerComputerComponent.builder()
.application(application)
.build()
.inject(this)
14. SubComponent
我們有時(shí)會(huì)遇到這么一種情況,一個(gè)module的provide方法的參數(shù)是另外一個(gè)module的provide的方法的返回值,比如:
class Member
class MemberA @Inject constructor(val member: Member)
@Module
class MemberModule {
@Provides
fun provideMember(): Member {
return Member()
}
}
@Module
class MemberAModule {
@Provides
fun provideMemberA(member: Member): MemberA {
return MemberA(member)
}
}
我們要?jiǎng)?chuàng)建MemberA對(duì)象,需要一個(gè)Member對(duì)象,但是Member對(duì)象是另外一個(gè)Module提供的,我們這時(shí)應(yīng)該怎么辦?我們有以下兩種方法:
- Component dependencies
我們可以在MemberComponent中顯式暴露Member對(duì)象,并在MemberAComponent中聲明依賴MemberComponent,代碼如下:
@Component(modules = [MemberModule::class])
interface MemberComponent {
//暴露member對(duì)象,方便其他component調(diào)用
fun member(): Member
}
@Component(modules = [MemberAModule::class], dependencies = [MemberComponent::class])
interface MemberAComponent {
fun inject(subComponentActivity: SubComponentActivity)
}
在注入的時(shí)候,我們先創(chuàng)建被依賴的Component,在創(chuàng)建DaggerMemberAComponent的時(shí)候依次傳入MemberAModule對(duì)象和DaggerMemberComponent
val daggerMemberComponent = DaggerMemberComponent.create()
DaggerMemberAComponent
.builder()
.memberAModule(MemberAModule())
.memberComponent(daggerMemberComponent)
.build()
.inject(this)
- Subcomponent
我們也可以利用Subcomponent,在MemberComponent中聲明一個(gè)返回值為MemberBComponent的方法,傳入的參數(shù)為MemberBModule,在MemberBComponent上把@Component換成@Subcomponent注解,其余的和@Componen一樣,代碼如下
@Component(modules = [MemberModule::class])
interface MemberComponent {
fun createSub(): MemberBComponent
}
@Subcomponent(modules = [MemberBModule::class])
interface MemberBComponent {
fun inject(subComponentActivity: SubComponentActivity)
}
注意在注入的時(shí)候,利用daggerMemberComponent來創(chuàng)建我們的daggerMemberComponent來完成注入
val daggerMemberComponent = DaggerMemberComponent.create()
daggerMemberComponent.createSub().inject(this)
15.Subcomponent.Builder
和前面提到的@Component.Builder一樣,Component關(guān)聯(lián)的Module的一個(gè)Provide方法需要一個(gè)參數(shù),我們可以自己去創(chuàng)建一個(gè)Builder,并通過@BindsInstance來注解一個(gè)方法來傳入?yún)?shù)
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): ComputerComponent
}
同樣,在SubComponent中,我們同樣可以利用類似的方法來傳入?yún)?shù)給Module來創(chuàng)建我們需要的依賴,實(shí)現(xiàn)這一目標(biāo)需要以下幾個(gè)步驟
- 在SubComponent內(nèi)部創(chuàng)建一個(gè)Builder接口,然后創(chuàng)建兩個(gè)方法,一個(gè)方法傳入我們Module需要的參數(shù),返回值為Builder類型,并且在方法上加上@BindsInstance注解;另一個(gè)方法返回SubComponent,如下
@Subcomponent(modules = [SonModule::class])
interface SonComponent {
fun inject(subComponentBuilderActivity: SubComponentBuilderActivity)
@Subcomponent.Builder
interface Builder {
fun build(): SonComponent
@BindsInstance
fun name(name: String): Builder
}
}
- 在Component創(chuàng)建一個(gè)返回類型為我們剛才新建的Builder接口的方法
@Component(modules = [FatherModule::class])
interface FatherComponent {
fun createSonBuilder(): SonComponent.Builder
}
- 在注入的時(shí)候,先創(chuàng)建Component,然后調(diào)用Component的創(chuàng)建SubComponent的Builder的方法來創(chuàng)建Builder,再利用Builder創(chuàng)建SubComponent
DaggerFatherComponent.builder().build().createSonBuilder().name("hankuke").build()
.inject(this)
以上就是dagger2的內(nèi)容,鏈接在這里
下面我們?cè)谥vdagger.android,主要是和Android相關(guān)的東西
16.在安卓中使用注入
我們可以在Android里面按照如下的方式完成注入:
DaggerMainComponent
.builder()
.build()
.inject(this)
但是這么寫一是很臃腫,幾乎每個(gè)需要注入的地方都要這么寫,而是幾乎每個(gè)需要注入的地方代碼都一樣,顯得有些不太好。當(dāng)然在Android里面,dagger2提供了更簡單的方式,我們可以按照以下幾個(gè)步驟來完成Android中的注入:
- 在AppComponent中引入AndroidInjectionModule
@Singleton
@Component(modules = [AndroidInjectionModule::class,MainActivityModule::class])
interface AppComponent {
fun inject(app: App)
}
- 聲明Activity的Subcomponent并實(shí)現(xiàn)AndroidInjector接口,然后在SubComponent內(nèi)部聲明一個(gè)Factory并實(shí)現(xiàn)AndroidInjector.Factory
@Subcomponent(modules = [UserModule::class])
interface MainActivitySubcomponent : AndroidInjector<MainActivity> {
@Subcomponent.Factory
interface Factory : AndroidInjector.Factory<MainActivity>
}
- 編寫我們的UserModule類和User類
data class User(val name: String, val age: Int)
@Module
class UserModule {
@Provides
fun provideUser(): User = User("lufei", 20)
}
- 聲明ActivityModule并和ActivitySubcomponent建立關(guān)聯(lián),創(chuàng)建一個(gè)方法聲明綁定關(guān)系
@Module(subcomponents = [MainActivityModule_ContributeMainActivity.MainActivitySubcomponent::class])
abstract class MainActivityModule {
@Binds
@IntoMap
@ClassKey(MainActivity::class)
abstract fun bindMainActivityInjectorFactory(factory: MainActivitySubcomponent.Factory): AndroidInjector.Factory<*>
}
- 讓我們的Application實(shí)現(xiàn)HasAndroidInjector接口,并且注入一個(gè)DispatchingAndroidInjector<Any>作為HasAndroidInjector實(shí)現(xiàn)方法androidInjector()的返回值
class App : Application(), HasAndroidInjector {
@Inject
lateinit var androidInjector: DispatchingAndroidInjector<Any>
override fun androidInjector(): AndroidInjector<Any> {
return androidInjector
}
}
- 在Application的onCreate()方法里面為Application注入
override fun onCreate() {
super.onCreate()
DaggerAppComponent.create().inject(this)
}
- 在Activity的onCreate()的super.onCreate()方法之前為當(dāng)前Activity注入
class MainActivity : AppCompatActivity() {
@Inject
lateinit var user: User
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
user.toString().log()
}
}
-大功告成
17.更加簡化的方式
上面的代碼已經(jīng)可以完成我們的需求,但我們還有一種更加簡單的方式來完成對(duì)Activity的注入。
我們先刪除MainActivitySubcomponent類,并在MainActivityModule中聲明下面的方法:
@ContributesAndroidInjector(modules = [UserModule::class])
abstract fun contributeMainActivity():MainActivity
來代替
@Binds
@IntoMap
@ClassKey(MainActivity::class)
abstract fun bindMainActivityInjectorFactory(factory: MainActivitySubcomponent.Factory): AndroidInjector.Factory<*>
重新編譯項(xiàng)目,我們可以看到dagger自動(dòng)幫我們生成了一個(gè)類MainActivityModule_ContributeMainActivity,類代碼如下:
@Module(subcomponents = MainActivityModule_ContributeMainActivity.MainActivitySubcomponent.class)
public abstract class MainActivityModule_ContributeMainActivity {
private MainActivityModule_ContributeMainActivity() {}
@Binds
@IntoMap
@ClassKey(MainActivity.class)
abstract AndroidInjector.Factory<?> bindAndroidInjectorFactory(
MainActivitySubcomponent.Factory builder);
@Subcomponent(modules = UserModule.class)
public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> {
@Subcomponent.Factory
interface Factory extends AndroidInjector.Factory<MainActivity> {}
}
}
我們可以看到,我們?cè)谖春喕暗牟僮?,如聲?strong>SubComponent類,聲明** bindAndroidInjectorFactory方法,聲明@Subcomponent.Factory**工廠類,都由dagger幫助我們完成了。