你所看到较轻松的Dagger2(使用方式)

上篇简单介绍了一下依赖注入以及为什么我们要用依赖注入.

这篇主要介绍一下Dagger2的使用方法 并分析一下Dagger2的源码看看它是怎么实现的。

Dagger2用法还是蛮简单的,首先我们在Project根目录的gradle中添加apt依赖

//添加apt依赖


classpath'com.neenbedankt.gradle.plugins:android-apt:1.8'

在我们的Module app gradle里添加apt插件

//添加如下代码,应用apt插件


applyplugin:'com.neenbedankt.android-apt'

然后添加dagger2依赖以及注解依赖


compile'com.google.dagger:dagger:2.4'

apt'com.google.dagger:dagger-compiler:2.4'

//java注解

compile'org.glassfish:javax.annotation:10.0-b28'

好了喝杯咖啡等待我们gradle构建完毕吧. 所有依赖添加完后我们就可以使用了.

这里我们以一个MVP小例子举例,先介绍Dagger2的第一种用法
我们传统的MVP写法基本似这样子滴
这是我们创建的Activity v层:


public class MainActivity extends AppCompatActivity implements BaseView{

    DemoPresenter mDemoPresenter;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.activity_main);

         @Override

         public voidsetXxx() {

         }

}

我们创建一个Presenter:

public class DemoPresenter {

         private BaseView mBaseView;

         private DemoModule mDemoModule;

         public DemoPresenter(BaseView baseView) {

         mBaseView= baseView;

         mDemoModule=newDemoModule();

 }

          public void   getPerson() {

          Person person =mDemoModule.getPerson();

          if(person.mMsg.equals("1")) {

                mBaseView.setXxx();

             }

       }

}

然后创建一个Module :

public class DemoModule {

        publicPersongetPerson(){

            Person p=null;

           try{

               Thread.sleep(1000);

               p=newPerson("wubo","11");

             }catch(InterruptedException e) {

                e.printStackTrace();

             }

           return  p;

        }

}

好了这里我们Module 用Thread睡以下假装请求接口数据,好传统我们做法是在Activity的onCreate()中

DemoPresenter demoPresenter =new DemoPresenter(this);

然后在合适的地方调用

demoPresenter.getPerson(); 

现在有了Dagger2我们就不需要这样写了 我们可以在MainActivity presenter成员变量上加上@Inject注解

@Inject
DemoPresenter  mDemoPresenter;  

然后在presenter的构造上同样加上@Inject注解

public class DemoPresenter {
       
         private BaseView mBaseView;

         private DemoModule mDemoModule;

         @Inject
         public DemoPresenter(BaseView baseView) {
          mDemoModule=newDemoModule();
         }
          public void   getPerson() {

          Person person =mDemoModule.getPerson();

          if(person.mMsg.equals("1")) {

                mBaseView.setXxx();
             }
          }
     }

当我们在MainActivity用@Inject标注后Dagger会去标注的这个类的构造上寻找是否同样有@Inject标注如果有的话生成这个对象,当然如果构造上面你没有加@Inject那么是不会生成对象的请看官网文档说明

If your class has @Inject-annotated fields but no @Inject-annotated constructor, Dagger will inject those fields if requested, but will not create new instances. Add a no-argument constructor with the @Inject annotation to indicate that Dagger may create instances as well.

好了现在注解加了对象也生成了,可是怎么把生成对象添加到我们依赖的MainActivity中呢?这就要用到Component,Component是一个桥梁它连接我们的宿主和依赖
我们新创建一个Compnoent接口,注意Component是不需要我们自己去实现的我们只需要去定义接口和实现方法,具体实现细节Dagger会自动帮我们生成是不是灰常贴心。

@Component (modules = {Module.class})
public interface Compnoent {
    void inject(MainActivity mainActivity);
}
(modules = {Module.class})

这里面我们要说明一下这个Component需要依赖哪些Module我们可以指定多个这里我们指定Module
贴上Module代码

@dagger.Module
public class Module {

    private BaseView mBaseView;

    public Module(BaseView baseView){

        mBaseView = baseView;
    }

    @Provides
    public BaseView getBaseView(){
        return mBaseView;
    }
}

这里我创建了一个Module构造里面参数传递宿主类也就是我们的MainActivity至于为什么这么继续看,下面定义了一个方法使用了
@Provides 咦这是什么东东,这个就是我们提供依赖对象的,比如
说我们可以new出来的对象可以用@Inject去注解构造,那么无法new
出来的对象怎么使用@Inject呢,比如

Interfaces can’t be constructed.
Third-party classes can’t be annotated.
Configurable objects must be configured!

所以Dagger给我们提供了Provides , Provides 是这样的在Dagger帮我们去创建依赖对象时,依赖对象中存在依赖对象或者构造中存在参数的时候,Dagger是没有这么智能也帮我们自动去生成的,这个时候Dagger会去@Module 类中 @Provides 依赖的方法找 哪个方法返回值复核依赖那么就赋值给这个依赖。

好了所以需要添加的代码我们添加完毕,现在我们在需要依赖的地方(比如MainActivity中的onCreate()中)调用

//方法一
DaggerCompnoent.builder().module(new Module(this)).build().inject(this);

就可以使用mDemoPresenter了

接下来我们介绍第二种依赖方式:
第二种方法我们不需要去使用@Inject注解了,其实我个人认为第二种方法不是依赖注入了因为这种方式生成的对象并不是Dagger注入进去的而是我们自己生成的只不过不是在宿主中生成了,可能有点绕我们继续看下去就会清除了。
第二种方式我们把所有使用@Inject全部去掉, 同样的还需要创建Module和Compnoent,Module创建的代码跟方式跟上面的一模一样,Compnoent 需要我们改一改

//之前我们是这样创建的
@Component (modules = {Module.class})
public interface Compnoent {
    void inject(MainActivity mainActivity);
}

//现在我们改成这样不需要传递宿主类了
@Component (modules = {Module.class})
public interface Compnoent {
    DemoPresenter getPresenter();
}

我们看到上面我们把代码改成了返回一个DemoPresenter 的方法,为什么要这么做呢,因为Dagger会帮我们去实现Component 注解的所有方法,当Dagger实现getPresenter()方法需要返回一个DemoPresenter 时候它怎么办呢?我们前面说了所有依赖中需要的依赖Dagger都会去Module中的Provide去找,所以我们前面的Module中同样需要改动的,我们添加一个
拿到DemoPresenter 的方法,你不添加Dagger怎么找的到呢,

@dagger.Module
public class Module {

    private BaseView mBaseView;

    public Module(BaseView baseView){

        mBaseView = baseView;
    }
    @Provide
    public DemoPresenter getPresenter(){
        return new DemoPresenter (mBaseView );
    }
}

现在我们可以在MainActivity中这么调

 //方法二
DemoPresenter mDemoPresenter =DaggerCompnoent.builder().module(new Module(this)).build().getPresenter();

这样我们就直接生成了一个DemoPresenter 对象
我们总结一下二种方式的区别
方法一: 通过在宿主类(MainActivity)中的依赖上添加@Inject,然后在依赖类的构造上@Inject ,Dagger自动生成依赖类的对象,然后创建一个@Module依赖的Module类,通过Module的构造方法传入宿主类,声明成员变量,然后添加一个@Provide依赖的方法,方法返回宿主对象也就是我们声明的成员变量.最后我们创建一个@Component依赖的Component接口Component 要申明我们要依赖的Module (modules = {Module.class}) Component接口中申明一个方法,方法中参数传递我们的宿主对象, void inject(MainActivity mainActivity);
然后在宿主类中调用
DaggerCompnoent.builder().module(new Module(this)).build().inject(this);

方法二:
创建一个@Module依赖的Module类,通过Module的构造方法传入宿主类,声明成员变量,然后添加一个@Provide依赖的方法,方法返回宿主对象也就是我们声明的成员变量,再多添加一个@Provide


Dagger还提供了@Signal

 @Provide
    public DemoPresenter getPresenter(){
        return new DemoPresenter (mBaseView );
    }

然后Component接口改成这样

@Component (modules = {Module.class})
public interface Compnoent {
    DemoPresenter getPresenter();
}

宿主类中我们这样直接生成依赖对象

 //方法二
DemoPresenter mDemoPresenter =DaggerCompnoent.builder().module(new Module(this)).build().getPresenter();

二种方式已经介绍完毕,艾玛,写的累死宝宝了,好了,使用方法介绍完毕,现在我们解开Dagger神秘的面纱看看Dagger是怎么自动生成代码的是怎么把依赖注入到宿主类中的,敬请期待你所看到最轻松的Dagger2讲解(源码分析)

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

推荐阅读更多精彩内容