本文是基于googlesamples的android-architecture的todo-mvp-dagger分支进行解析
Dagger-Android
注意
@Binds 在Module中使用 例如
abstract TasksDataSource
provideTasksLocalDataSource(TasksLocalDataSource
dataSource);
这里参数TasksLocalDataSource(实现类)就是用来提公供TasksDataSource(接口类)
对于类中方法的@Inject标注调用时机。 通过对DaggerApplication的重写,发现
@Inject
public void setListener(){
}
1.此方法在Application被Inject(this)之后进行自动调用。 2.另一种情况,@Inject标记的构造函数调用后进行自动调用
Scope
Scope :用来限定单例范围和绑定生命周期 例如Dagger2里系统的Singleon,如果和Application绑定,就是全局单例,如果和Activity绑定就是Activity生命周期内单例。 如果自己新建AppScope,然后用于Application的inject绑定,则AppScope也表示全局单例
Component
用来绑定组件(Application Activity等)和类实例的桥梁。 通过Module或者@Inject来提供实例 如果提供同样的类实例,先从Module里找,然后从@Inject来找 例如,如果Activity需要使用Application的提供全局的实例,需要在Activity Component里dependencies AppComponent,并且在Builder提供set AppComponent实例的方法。 这样Activity在inject之后,就可以使用Application提供的实例
Module
用来提供实例的,再方法上标注@Provides 方法上添加Scope用来限定单例区域,即跟随Component绑定的组件的区域及生命周期 方法上添加@Name或者自定义限定符,用来区分返回同一个类的引用
SubComponent
两个类有公用的部分,可以使用SubComponent来进行关联 使用方法,由于子类不能单独生成DaggerChildComponent,而是根据父类来获取的。 所以需要在父类的Component 接口中加入SonComponent.Builder sonComponent()方法来获取子Component.Builder 获取后跟父类一样进行绑定子类 父类和子类的关联,可以通过父类的Module,@Module(subcomponent = ChildComponent.class)
Scope单例
对Module里提供实例加入Scope注解,则会得到对应的局部单例
- 对于未加Scope注解的,查看生成的代码,发现用如下方法生成实例:
ApplicationModule_ProvideUserEntityFactory.proxyProvideUserEntity()这里的proxyProvideUserEntity()方法调用了ApplicationModule.provideUserEntity()方法,这个方法则是调用我们Module里的对实例的实例化。每次调用都会新生成一个实例- 而对于加入Scope注解的,则会在DagerAppComponent代码里,通过provideUserEntityProvider.get()来获取实例。 而生成这个Provider则是DoubleCheck.provider(ApplicationModule_ProvideUserEntityFactory.create())此方法生成。
- 首先create()方法生成一个单例的工厂实例。
- DoubleCheck的方法provide,则是将生成的实例工厂包装成DoubleCheck类,这里通过get方法拿到提供的实例。
- 再看看DoubleCheck的get()方法,首先判断是否已经有了赋值的instance,如果有,直接返回instance。
- 如果没有,则通过传入的provider.get()去获取。而这个get方法就是工厂的get方法,最终调用的就是上面的没给Module实例加Scope的获取实例方法。这里拿到后会赋值给instance。