开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情
我们在平时做一个项目的时候,可能不止一个模块,可能会有很多个library,总不能把所有library全部注入到一个component里面去吧。所以我们就需要将component拆成多个,拆成多个当然这几个是需要有一定的关系才能有关联。在dagger2里面提供两种方式一种依赖(dependencies)另外一种就是subcomponent。今天我们就先看看subcomponent的做法。
使用subcomponent这个是一个继承的关系。把一个component标记为一个subcomponent当然需要@Subcomponent这个关键字,subcomponent如下:
@Subcomponent(modules=[SubModuleExample::class])
interface SubComponentExample {
@Subcomponent.Builder
interface Builder{
fun build():SubComponentExample
}
fun inject(mainActivity: MainActivity)
}
这个里面有一个必要的因素,把就是 @Subcomponent.Builder,这个必须要进行声明.在调用地方:
daggerExampleComponent.subComponentExample().build().inject(this)
当然上次我们讲了创建实例可以使用builder也可以使用factory,factory的写法如下:
@Subcomponent.Factory
interface Factory{
fun create():SubComponentExample
}
那在使用的地方就是:
daggerExampleComponent.subComponentExample().create().inject(this)
只是创建实例的方式不一样,其实都大同小异。
上面的SubModuleExample是subcomponent里面提供的provider
@Module
class SubModuleExample {
@Provides
fun providerTasla():Car{
return Tasla()
}
}
其实也很简单就是简单声明一个module。
那下面看最重要的部分,如果关联到parent component里面:
interface ExampleComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun setContext(context: Context):Builder
fun build(): ExampleComponent
}
fun subComponentExample():SubComponentExample.Factory
}
其实只需要在parent component里面添加一个返回subcomponent的实例就好了。当然这里根据subcomponent声明的创建方式返回,这里是使用factory,如果使用Builder那么就返回:SubComponentExample.Builder
我们现在是在subcomponent的module里面创建了一个car的实例,car是一个interface,实现类是tasla,如下:
interface Car {
fun getCarName():String
}
class Tasla @Inject constructor():Car {
override fun getCarName(): String {
return "Tasla"
}
}
我们把这个类在MainActivity中使用,但是这个是属于subcomponent里面的,所以我们需要把MainActivity注入到subComponent里面去,要不然注入就失败了,刚开始为这个问题困了好久,最后才发现:
fun inject(mainActivity: MainActivity)
在使用的地方:
val daggerExampleComponent = DaggerExampleComponent.builder().setContext(this.applicationContext).build()
daggerExampleComponent.subComponentExample().create().inject(this)
dagger初始化,以及subcomponent的初始化
@Inject
lateinit var tasla: Car
如果Car这个类
Log.i("daggerExample","car name:${tasla.getCarName()}")
打印结果:
I/daggerExample: car name:Tasla
我们看看生成的类里面:
private MainActivity injectMainActivity(MainActivity instance) {
...
SubModuleExample_ProviderTaslaFactory.providerTasla(subModuleExample));
return instance;
}
这一段是给MainActivity注入的对象,是通过subModuleExample来提供
public SubComponentExample.Factory subComponentExample() {
return new SubComponentExampleFactory(exampleComponentImpl);
}
这一段是创建subComponent的实例,从创建实例可以看出,它把parent的comoponent实例对象传入到了subcomponent里面,那意思就是它可以访问父类public提供的所有注入了。