关于Dagger2的学习

看了很多关于Dagger2的中文用法介绍,看过之后的感受一言难尽。
这里是几篇相对好一些的。
https://blog.csdn.net/mq2553299/article/details/77485800
//www.greatytc.com/p/65737ac39c44
//www.greatytc.com/p/22c397354997
下面的链接是一篇Dagger2英文android教学,比大部分中文的要好很多。(需要翻墙)
https://medium.com/@harivigneshjayapalan/dagger-2-for-android-beginners-introduction-be6580cb3edb
顺便附上Dagger2的官网和代码(包括example)以及google的官方demo
https://google.github.io/dagger/users-guide
https://github.com/google/dagger
https://github.com/googlesamples/android-architecture/tree/todo-mvp-dagger

简单的说下思路

理解依赖注入(DI)

A类中有B类的对象,就叫A类依赖B类,B类是A类的依赖。
这里有两个War类,他们有不同的构造方法。

public class War {

    private Starks starks;
    private Boltons boltons;

    public War(){
        starks = new Starks();
        boltons = new Boltons();

        starks.prepareForWar();
        starks.reportForWar();
        boltons.prepareForWar();
        starks.reportForWar();
    }
}
public class War {

    private Starks starks;
    private Boltons boltons;
    
    //DI - getting dependencies from else where via constructor
    public War(Starks starks, Boltons bolton){
        this.starks = starks;
        this.boltons = bolton;
    }

    public void prepare(){
        starks.prepareForWar();
        boltons.prepareForWar();
    }

    public void report(){
        starks.reportForWar();
        boltons.reportForWar();
    }

}

对于第一种构造方法,如果Starks和Boltons类的构造方法发生变化,需要修改War类中的代码,耦合严重。
对于第二种构造模式,在实例化war对象时需要提供一个Starks对象和Boltons对象,这个过程——将依赖注入的过程在程序的主方法中实现。

public class BattleOfBastards {

    public static void main(String[] args){

        Starks starks = new Starks();
        Boltons boltons = new Boltons();

        War war = new War(starks,boltons);
        war.prepare();
        war.report();
    }
}

在android开发过程中,这个过程在Activity的onCreate(Bundle savedInstanceState)方法和Application的onCreate()方法以及Fragment的onAttach(Context context)方法中实现。
(该内容来自英文教学,中文的我没看到过)
(这是Activity和Fragment生命周期的第一个方法,避免出现对象为null的错误)

Dagger2的作用就是通过一系列工厂方法实例化依赖注入所需要的对象。

具体实现过程

建议查看英文教程
https://medium.com/@harivigneshjayapalan/dagger-2-for-android-beginners-introduction-be6580cb3edb
要记住Dagger2的实现思想——在实例化一个对象的时候将它所需要的依赖注入其中。这里有三个基本问题,谁是依赖类,被依赖的对象需要注入到哪里去,具体注入方式。重点就在于具体注入方式。

注意其编写代码的思路
1、Top @Component
2、@Module
3、连接Modules
4、关联Component和Module
5、编译和注入

这和Dagger2官网的User Guide中的思路基本相反
声明依赖,满足依赖,建立图表

剩下的则是注意懒加载,单例和范围限定符等常用注解。

关于接口和MVP模式

在MVP模式中,一般会有一个Contract接口,该接口中有Presenter和View两个接口,我们需要实现这两个接口,并分别在接口的实现类中调用另一个接口的方法。为了解耦在实现类中,我们声明的是接口而不是实现类。

我们先看Dagger2官方example中是如何声明接口依赖的。


Dagger2_example

这个是第一种声明方法(在构造方法中使用了@Inject)。Pump为接口,PumpModule是Module类,Thermosiphon是接口的实现类。

interface Pump {
  void pump();
}

@Module
abstract class PumpModule {
  @Binds
  abstract Pump providePump(Thermosiphon pump);
}

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }

  @Override public void pump() {
    if (heater.isHot()) {
      System.out.println("=> => pumping => =>");
    }
  }
}

在声明的过程中,@Inject标注了Thermosiphon类的构造方法,抽象PumpModule类中用@Binds标注了抽象方法providePump(Thermosiphon pump),该方法返回接口Pump。在最终的使用过程中该方法并没有使用,该方法是用于编译时生成代码的绑定声明。

这个是第二种声明方法(使用Module类)。

@Module(includes = PumpModule.class)
class DripCoffeeModule {
  @Provides
  @Singleton
  Heater provideHeater() {
    return new ElectricHeater();
  }
}

class ElectricHeater implements Heater {
  boolean heating;

  @Override public void on() {
    System.out.println("~ ~ ~ heating ~ ~ ~");
    this.heating = true;
  }

  @Override public void off() {
    this.heating = false;
  }

  @Override public boolean isHot() {
    return heating;
  }
}

interface Heater {
  void on();
  void off();
  boolean isHot();
}

需要注意的就是DripCoffeeModule 类中唯一的方法,声明的返回类型是接口,返回了一个新的ElectricHeater对象。

在谷歌的官方example中,Activity管理Fragment的生命周期,Fragment用于展示数据,Presenter被注入到了Fragment里,Fragment被注入到Activity中。官方example使用了Dagger-Android组件,我们暂时先不管这个。以TaskDetail为例,可以看到TaskDetailPresenter的构造方法被@Inject标注,这是第一种声明方法。在TaskDetailPresenterModule 类中有抽象方法statitsticsPresenter(TaskDetailPresenter presenter),这和之前提到的是一样的。

final class TaskDetailPresenter implements TaskDetailContract.Presenter {
   ...
   @Inject
    TaskDetailPresenter(@Nullable String taskId,
                        TasksRepository tasksRepository) {
        mTasksRepository = tasksRepository;
        mTaskId = taskId;
    }
   ...
}

@Module
public abstract class TaskDetailPresenterModule {


    @FragmentScoped
    @ContributesAndroidInjector
    abstract TaskDetailFragment taskDetailFragment();

    @ActivityScoped
    @Binds
    abstract TaskDetailContract.Presenter statitsticsPresenter(TaskDetailPresenter presenter);

    @Provides
    @ActivityScoped
    static String provideTaskId(TaskDetailActivity activity) {
        return activity.getIntent().getStringExtra(EXTRA_TASK_ID);
    }
}

这里另外要注意的是statitsticsPresenter方法是被@ActivityScoped标注的,这意味着它的生命周期应该和Activity一致。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,423评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,147评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,019评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,443评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,535评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,798评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,941评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,704评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,152评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,494评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,629评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,295评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,901评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,978评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,333评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,499评论 2 348

推荐阅读更多精彩内容