dagger的使用

拖延症犯了...抓狂...赶紧补上吧

一.背景

最开始用dagger是因为项目需求,后来用着用着就太爽了,少写了不少代码,整个项目都清爽了,隔了一段时间没敲代码,用法都快忘干净了,所以赶紧写下来


二.基本介绍

什么引入方式我就不讲了,github上面都有

一开始用dagger,主要是那些注解看不懂是什么意思,那就先把注解是啥意思写出来,然后再结合代码解释,这样就简单很多了。

· @Inject 带有此注解的属性或构造方法将参与到依赖注入中,Dagger2会实例化有此注解的类

· @Module 带有此注解的类,用来提供依赖,里面定义一些用@Provides注解的以provide开头的方法,这些方法就是所提供的依赖,Dagger2会在该类中寻找实例化某个类所需要的依赖

· @Component 用来将@Inject和@Module联系起来的桥梁,@Module中获取依赖并将依赖注入给@Inject也就是指定了查找的范围从@Module中的去找就行

·  @scope

· @subComponent


//MainActivity.java


MainPresenter.java


MainModule.java


MainComponent.java



实际效果就是这样




可以看出很简单的就引入了MainPresenter,我们来分步讲解下大概的过程

1.MainActivity中声明MainPresenter加上@inject表明MainPresent需要外部注入到MainActivity,也就是MainActivity依赖于MainPresenter,注意使用@inject不能用private修饰符修饰累的属性(后面的源码会讲为什么

2. 然后在MainPresent 的构造函数加上 @inject ,这样 MainActivity 里的 mainPresenter 与他的构造函数建立了某种联系( 可以理解为当看到@inject标记时,就会到他的构造方法中,如果这个构造方法也被@inject标记的话(如果没有的话就是另外一种方法),就会自动初始化这个类,从而完成依赖注入,但是这之间肯定要桥梁也就是component)。

3.Component是一个接口或者抽象类,用@Component注解标注,我们在里面定义了一个inject()方法,参数MainActivity(其实我觉得就是说在MainActivity中需要依赖注入,去这里面找)

MainActivity.java

DaggerMainComponent.builder()
        .mainModule(newMainModule(this))
        .build()
        .inject(this);

然后就将@inject注解此时Component就将@Inject注解的mainPresenter与其构造函数联系了起来原理后面讲


4.

MainModule是一个注解类,用@Module注解标注,主要用来提供依赖。

请注意!!!之前通过构造方法和使用的地方申明@inject就可以完成依赖,那你会问为什么还用@module呢?也就是第二条说的另外一种方法

因为之前我们@inject的时候,那些东西有构造函数,所以Module类主要是为了提供那些没有构造函数的类的依赖,这些类无法用@inject标注,比如第三方类库,系统类,以及上面示例的View接口。

我们在MainModule类里声明了MainContract.View成员属性,在构造方法里将外界传进来的view复制给mView并通过一个@Provides标注的以provide开头的方法,将这个view返回,这个以provide开头的方法就是提供以来,我们可以提供创建多个方法来提供不同的依赖。

@Module
public class MainModule {
    private finalMainContract.View mView;

    public MainModule(MainContract.View view) {
        mView = view;
    }

    @Provides
    MainContract.ViewprovideMainView() {
        returnmView;
    }
}

简单的看就是构造函数得到mVIew(之前在activity中有new MainModule)然后通过注解@Provides + 方法provideMainView把这个view提供给有需要的地方

Module要发挥作用还是要依靠于Component,一个Component类可以包含多个Module类,用来提供依赖。

DaggerMainComponent.builder()
        .mainModule(newMainModule(this))
        .build()
        .inject(this);


5.去实例化MainPresenter,发现构造函数有个参数,此时会在Module里查找提供这个依赖的方法,将该View传递进去,这样就完成了presenterView的注入。

下面讲原理了:

自动生成的代码在下面的目录下






MainModule_ProvideMainViewFactory.java


针对create这个方法的入参可以在下面的component中查看,然后这个的get方法就给下面的MainPresenter_factory提供入参View.

MainPresenter_factory.java


针对这个create方法,里面需要传参viewProvider,然后就可以给MainPresenter初始化提供他需要的View关键来了ViewProvider从哪来?是从上面来的

MainActivity_MembersInjector.java


针对create可以看到入参是Provider<MainPresenter>但是在MainPresenter_factory中提供的Factory<MainPresenter>,所以这也是一个问题???


DaggerMainComponent.java





在init方法中可以看到入参需要builder.mainModule,这个入参是从下面拿到

DaggerMainComponent.builder()
        .mainModule(new MainModule(this))
        .build()
        .inject(this);
然后依次给MainModule_factory ,MainPresenter_factory,MainActivityInjectorMember_facory, 然后最关键的是inject(this)!!!

public void inject(MainActivity activity) {
  mainActivityMembersInjector.injectMembers(activity);
然后看下面这个


然后看到injectMember就知道为什么inject的方法不能用Private.然后就给@inject的对象给赋值了






DaggerMainComponent.builder()
        .mainModule(newMainModule(this))
        .build()
        .inject(this);

DaggerMainComponent.builder()
        .mainModule(newMainModule(this))
        .build()
        .inject(this);









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值