您当前的位置: 首页 >  android

Kevin-Dev

暂无认证

  • 0浏览

    0关注

    544博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【Android -- 开源库】Dagger2 的基本使用

Kevin-Dev 发布时间:2018-07-09 15:41:13 ,浏览量:0

在这里插入图片描述

前言

Dagger2 已经出来挺久了,网上相关的教程也很多,普遍都说它比较难上手。 相比起其他框架确实如此,但只要学习后加以实践,还是比较好明白的,说不定你还会从此对它爱不释手。

推荐阅读:

  • https://blog.csdn.net/lisdye2/article/details/51942511
  • https://www.jianshu.com/p/24af4c102f62
1. 什么是Dagger2

Dagger2 是一个依赖注入(Dependency Injection)框架。

2. 使用Dagger2有什么好处
  • 解耦 假设有一个A类,项目中很多地方都使用到它(在很多地方通过new A()对A实例进行了初始化)。然后由于需求变动,A的构造函数增加了一个参数。 好了,牵一发而动全身,你需要把各个new A()的地方都进行修改。 但如果是使用Dagger2进行管理,你只需在类实例的供应端进行修改即可。

  • 让功能实现更专注于功能实现 假设现在你需要调用A类的x()方法来实现某功能,但是A类的构造过程相当的复杂(这样的例子可以参考GreenDao中获取XXXDao、Retrofit中获取Observable请求)

public void xxx(){
    E e = new E();
    D d = new D(e);
    C c = new C();
    B b = new B(c,d);
    A a = new A(b);
    a.x();
}

结果6行代码中,构造实例a占了5行,调用x()方法实现功能却只占了1行。 但如果使用Dagger2进行管理,将a实例的构造过程移至实例供应端,则功能实现模块的代码会变成这样

@Injcet
A a;
public void xxx(){
    a.x();
}

这就是所说的让功能实现更专注于功能实现,而不必去管a实例的构造过程。

  • 更好地管理类实例 通常我们开发中会有两种类实例:
    • 一种是全局实例(单例),它们的生命周期与app保持一致。
    • 一种是页面实例,它们的生命周期与页面保持一致。
    • 通过Dagger2,我们可以使用一个组件专门管理全局类实例(也免去了单例的写法,不用考虑饿汉懒汉什么的);然后各个页面也有各自组件去管理它们的页面实例。
    • 这样不管是对于实例的管理,还是项目的结构,都会变得更加的清晰明了。
使用

1. 添加依赖

compile 'com.google.dagger:dagger:2.14.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1'

2. 处理实例需求端 在实例需求端中,使用@Inject标注需要注入的实例变量。

public class UploadActivity extends AppCompatActivity{
    @Inject
    UploadPresenter mPresenter;
}

3. 处理实例供应端

  • 方式一:使用 Module
@Module
public class UploadActivityModule {
    @Provides
    UploadPresenter uploadPresenter() {
        return new UploadPresenter();
    }
}
  • 方式二:使用@Inject标注构造函数
public class UploadPresenter{
    @Inject
    public UploadPresenter() {
    }
}

注意: 方式一的优先级高于方式二,意思就是:

  • 在供应某实例时,会先通过方式一查找是否存在返回该实例的的方法
  • 如果存在,则获取实例并对外供应
  • 如果不存在,再通过方式二查找是否存在@Inject标注的构造函数
  • 如果存在,则将通过该构造函数构造实例并对外供应
  • 如果不存在,那将报错,因为无法供应所需的实例

4. 搭建桥梁

  • 使用@Component标注接口,表示它为桥梁。 (如果使用1.3.1的方式供应实例,则需在@Component(modules=xxx.class)中指明module。) 一个Component可以没有module,也可以同时有多个module。
  • 添加 void inject(实例需求端) 方法,表明实例供应端中的实例将交给该实例需求端。 通过这个方法,查找实例需求端中需要注入的实例有哪些(使用@Inject标注的那些实例),然后在实例供应端中获取所需的实例,最后注入到实例需求端中
  • 用来注入的方法,它的方法名不一定要是inject,可以随便取,一般都取inject。但该方法的返回类型必须为void
@Component(modules = UploadActivityModule.class)
public interface UploadActivityComponent {
    void inject(UploadActivity uploadActivity);
}

5. 编译,注入

  • 完成以上几步后,ReBuild一下项目以生成DaggerUploadActivityComponent类。
  • 在实例需求端中调用inject完成实例的注入
public class UploadActivity extends AppCompatActivity{
    @Inject
    UploadPresenter mPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //注入实例
        DaggerUploadActivityComponent.builder()
            .build()
            .inject(this);

        //注入后即可调用mPresenter中的方法了
        mPresenter.xxx();
    }
}
关注
打赏
1658837700
查看更多评论
立即登录/注册

微信扫码登录

0.0437s