Android-Dagger2小技巧

Dagger2入门

2019-06-02  本文已影响6人  WaterYuan

框架源码:https://github.com/google/dagger
Dagger 2 完全解析系列:
Dagger 2 完全解析(一),Dagger 2 的基本使用与原理
Dagger 2 完全解析(二),进阶使用 Lazy、Qualifier、Scope 等
Dagger 2 完全解析(三),Component 的组织关系与 SubComponent
Dagger 2 完全解析(四),Android 中使用 Dagger 2
Dagger 2 完全解析(五),Kotlin 中使用 Dagger 2
Dagger 2 完全解析(六),dagger.android 扩展库的使用


Dagger 2 完全解析(一),Dagger 2 的基本使用与原理
https://www.jianshu.com/p/26d9f99ea3bb

依赖注入就是将对象实例传入到一个对象中去(Denpendency injection means giving an object its instance variables)。依赖注入是一种设计模式,降低了依赖和被依赖对象之间的耦合,方便扩展和单元测试。

  1. 引入 Dagger 2
    查询版本号:https://search.maven.org/search?q=dagger
    implementation 'com.google.dagger:dagger:2.21'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.21'
    implementation 'com.google.dagger:dagger-android:2.21'
    implementation 'com.google.dagger:dagger-android-support:2.21'
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.21'

如何在gradle中定义变量(比如 版本号)并引用?

  1. 使用 @Inject 标注需要注入的依赖
    创建所依赖对象的实例
    @Inject可以标注成员变量及构造函数
    build 后可以在build/generated/source/apt目录下看到 Dagger 2 编译时生成的
  2. Component 桥梁
    @Component可以标注接口或抽象类,Component 桥梁可以完成依赖注入过程,其中最重要的是定义注入接口,调用注入接口就可以完成 Man 所需依赖的注入。
    build 后会生成带有Dagger前缀的实现该接口的类
    Component 就是连接依赖的对象实例和需要注入的实例属性之间的桥梁。Component 会查找目标类对应的成员属性注入类(即 MembersInjector<Man>),然后把依赖属性的工厂实例(即 Car_Factory.create())传给注入类,再使用 Component 一开始定义的接口就能完成依赖注入。
    注意,Component 中注入接口的参数必须为需要注入依赖的类型,不能是 Man 的父类或子类,注入接口返回值为 void,接口名可以任意。
    接下来只需要在 Man 中调用injectMan方法就能完成注入。
  3. Module
    使用@Inject标注构造函数来提供依赖的对象实例的方法,不是万能的,在以下几种场景中无法使用:
    * 接口没有构造函数
    * 第三方库的类不能被标注
    * 构造函数中的参数必须配置
    这时,就可以用@Provides标注的方法来提供依赖实例,方法的返回值就是依赖的对象实例,@Provides方法必须在Module中,Module 即用@Module标注的类。所以 Module 是提供依赖的对象实例的另一种方式。
    约定俗成的是@Provides方法一般以provide为前缀,Moudle 类以Module为后缀,一个 Module 类中可以有多个@Provides方法。
    接下来,需要把可以提供依赖实例的 Module 告诉 Component:
    CarModule_ProvideCarFactory 和之前的 Car_Factory 类似,都实现 Factory<Car> 接口。
    生成的 DaggerManComponent 和之前相比只改变了一个方法:
  4. 总结
    Dagger 2 最核心的三个部分
  1. 需要注入依赖的目标类,需要注入的实例属性由@Inject标注。
  2. 提供依赖对象实例的工厂,用@Inject标注构造函数或定义Module这两种方式都能提供依赖实例,Dagger 2 的注解处理器会在编译时生成相应的工厂类。Module的优先级比@Inject标注构造函数的高,意味着 Dagger 2 会先从 Module 寻找依赖实例。
  3. 把依赖实例工厂创建的实例注入到目标类中的 Component。
Dagger 2 最核心的三个部分

下面再讲述上面提到的在 Dagger 2 种几个注解的用法:

  • @Inject 一般情况下是标注成员属性和构造函数,标注的成员属性不能是private,Dagger 2 还支持方法注入,@Inject还可以标注方法
  • @Provides 只能标注方法,必须在 Module 中
  • @Module 用来标注 Module 类
  • @Component 只能标注接口或抽象类,声明的注入接口的参数类型必须和目标类一致。

完整代码:
https://github.com/WaterYuanData/AIDL/tree/master/teatdagger/src/main/java/com/yuan/teatdagger/dagger2
com.yuan.teatdagger.dagger2包下是@Inject构造函数注入
com.yuan.teatdagger.dagger2.module包下是@Module类@Provides方法注入


Dagger 2 完全解析(二),进阶使用 Lazy、Qualifier、Scope 等

  1. 在 provide 方法上加上@Named注解,用来区分
  2. 还需要在 Inject 注入的地方加上@Named注解,表明需要注入的是哪一种 Car

@Scope是元注解,是用来标注自定义注解的,MyScope 就是一个 Scope 注解

@Documented
@Retention(RUNTIME)
@Scope
public @interface MyScope {}

Scope 注解只能标注目标类、@provide 方法和 Component。Scope 注解要生效的话,需要同时标注在 Component 和提供依赖实例的 Module 或目标类上。Module 中 provide 方法中的 Scope 注解必须和 与之绑定的 Component 的 Scope 注解一样,否则作用域不同会导致编译时会报错。
Scope 作用域的本质:Component 间接持有依赖实例的引用,把实例的作用域与 Component 绑定,它们不是同年同月同日生,但是同年同月死。

  1. 例如 Component 有 ScopeA 和 ScopeB 标记,那么它可以和 ScopeA 的 ModuleA、ScopeB 的 ModuleB 绑定。所以准确的说应该是,Module 的 Scope 必须包含在 Component 的 Scope 中
  2. 一般一个 Activity 只需要一个 Component,但是一个 Component 可以绑定多个 Module
  3. 在 @BindingInstance 例子中,定义的是 Builder activity(Activity activity); ,所以后面只能注入 Activity 类型。
    而之前 Module 构造函数绑定依赖实例中,参数为 HomeActivity,但是后面的 provide 方法返回的类型为 Activity,所以也只能提供 Activity 类型的依赖。
  4. 在activity中注入了一个presenter,这个presenter在哪里被销毁的
    4.1首先,presenter 被你注入到的 Activity 引用了,所以在 activity 未被销毁前是不会被回收的
    4.2 如果你使用了 Scope 作用域的话,管理 presenter 的 Component 还会间接保留一份 presenter 的引用,所以 presenter 的生命周期还和 Component 绑定,如果 component 实例被 activity 保留的话,那么 component 和 presenter 的生命周期都和 activity 一样了。
    4.3 但是如果使用的 AppComponent 注入的话,AppComponent 被 application 保留实例,那么 presenter 的生命周期就会和 application 绑定了。

一个整合了大量主流开源项目高度可配置化的 Android MVP 快速集成框架
https://github.com/JessYanCoding/MVPArms/blob/master/MVPArms.md

Dagger2神器入门(一)
https://www.jianshu.com/p/dce5382fec5d

Dagger2从入门到放弃再到恍然大悟
https://www.jianshu.com/p/39d1df6c877d

Android_Dagger2篇——从小白最易上手的角度 + 最新dagger.android
https://www.jianshu.com/p/22c397354997

Dragger2快速入门浅析
https://blog.csdn.net/Jet_Green/article/details/80996657

深入浅出Dagger2 : 从入门到爱不释手
https://www.jianshu.com/p/626b2087e2b1

上一篇下一篇

猜你喜欢

热点阅读