美文网首页技术干货儿Android TestingDagger2
Android:dagger2让你爱不释手-终结篇

Android:dagger2让你爱不释手-终结篇

作者: 牛晓伟 | 来源:发表于2016-03-27 23:53 被阅读25994次

    前言

    如果您对dagger2的概念,整个依赖注入框架还不清楚,可以先了解下我的前2篇文章:
    Android:dagger2让你爱不释手-基础依赖注入框架篇
    Android:dagger2让你爱不释手-重点概念讲解、融合篇
    这2篇文章也收到好多网友的好评和提问,谢谢大家的支持。我大概总结了下提的问题:

    • dagger2到底能带来哪些好处?
    • dagger2怎么使用?

    因此我将结合这2点来进行本文的讲解。并且会有具体的sample。

    dagger2到底有哪些好处?

    咱们直奔主题:

    增加开发效率、省去重复的简单体力劳动
    首先new一个实例的过程是一个重复的简单体力劳动,dagger2完全可以把new一个实例的工作做了,因此我们把主要精力集中在关键业务上、同时也能增加开发效率上。
    省去写单例的方法,并且也不需要担心自己写的单例方法是否线程安全,自己写的单例是懒汉模式还是饿汉模式。因为dagger2都可以把这些工作做了。

    更好的管理类实例
    每个app中的ApplicationComponent管理整个app的全局类实例,所有的全局类实例都统一交给ApplicationComponent管理,并且它们的生命周期与app的生命周期一样。
    每个页面对应自己的Component,页面Component管理着自己页面所依赖的所有类实例。
    因为Component,Module,整个app的类实例结构变的很清晰。

    解耦
    假如不用dagger2的话,一个类的new代码是非常可能充斥在app的多个类中的,假如该类的构造函数发生变化,那这些涉及到的类都得进行修改。设计模式中提倡把容易变化的部分封装起来

    我们用了dagger2后。

    假如是通过用Inject注解标注的构造函数创建类实例,则即使构造函数变的天花乱坠,我们基本上都不需要修改任何代码。

    假如是通过工厂模式Module创建类实例,Module其实就是把new类实例的代码封装起来,这样即使类的构造函数发生变化,只需要修改Module即可。

    有个网友问过一个这样的问题,Module的构造函数也会发生变化,发生变化后,相应的new Module的类也发生变化,这就没有达到解耦的效果。首先解耦不是说让类之间或模块之间真的一点关系都没有了,解耦达到的目的是让一个类或一个模块对与自己有关联的类或模块的影响降到最低,不是说这种影响就完全没有了,这是不可能的。

    解耦还有个好处,就是方便测试,若需要替换为网络测试类,只需要修改相应的Module即可。

    项目中使用dagger2注意点

    具体的代码就不讲了,dagger2 sample地址,大家自行下载。这里重点说下dagger2对目标类进行依赖注入的过程,现在假设要初始化目标类中的其中一个依赖类的实例,那具体步骤就在下面:

    步骤1:查找Module中是否存在创建该类的方法。
    步骤2:若存在创建类方法,查看该方法是否存在参数
        步骤2.1:若存在参数,则按从**步骤1**开始依次初始化每个参数
        步骤2.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
    步骤3:若不存在创建类方法,则查找Inject注解的构造函数,
               看构造函数是否存在参数
        步骤3.1:若存在参数,则从**步骤1**开始依次初始化每个参数
        步骤3.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
    

    以上是dagger2进行的一次依赖注入的步骤,其实这个步骤是一个递归的过程,并且在查找类的实例的过程中Module的级别要高于Inject,这概念在上一篇讲过。

    下面在说下注意的几点

    • 一个app必须要有一个Component(名字可以是ApplicationComponent)用来管理app的整个全局类实例
    • 多个页面可以共享一个Component
    • 不是说Component就一定要对应一个或多个Module,Component也可以不包含Module
    • 自定义Scope注解最好使用上,虽然不使用也是可以让项目运行起来的,但是加上好处多多。

    总结

    好了关于dagger2的所有的概念知识点到此终于结束了,希望能帮助大家,与大家共勉,有问题可以随时与我沟通。

    dagger2 sample地址

    个人简介
    本人是一名android开发工程师,开发android多年,若有志同道合的朋友想联系我,可以加我的:qq/微信: 704451290

    欢迎各位多多交流,转载请标明出处。
    本人微信:704451290

    本人公众账号

    相关文章

      网友评论

      • miaoyongjun:假如是通过用Inject注解标注的构造函数创建类实例,则即使构造函数变的天花乱坠,我们基本上都不需要修改任何代码
        确定不用改吗?我加个String的参数呢
      • 9f6d46ac9717::smile: 其他人直接上一团代码、没思路不理解、到最后下来感觉毫无优势了。
      • 荒漠捕食者:没有群么?
      • 凸图土吐:dagger2 会不会有内存泄漏的问题呢?
      • 7f23d6c94f14:写dagger2写得最好的,没有之一
      • loneyzhou:作者你好,周末看了你的Dagger2三篇文章,概念思路很清晰,让人受益匪浅~先表示一下感谢~ 然后我还有个小疑问,文末你说到多个页面共享一个Component,类似局部单例的样子,但是这个Component是怎么样存在的呢?Application中的Component是全局单例,每个Activity中的可以算是每个页面使用,但是这个多页面Component的存在是怎样的形式呢?(在哪里创建,在哪里使用),多谢楼主答疑
        恋猫月亮: @loneyzhou DaggerxxxComponent是实际创建和注入,每次你使用它builder的时候,就创建了一个新的啊。比如你在Activiti每次都创建,那么Activity内,所有的fragment都可以共享这个component,这时候你可以用一个ActivityScope来约定这一规则。
        恋猫月亮:component类似连接器,提供连接module和实例注入等功能。可以看成针(component),把药注入到人(@Inject的类)。其中药是构造方法的参数【module提供/或不需要提供】。

        同时在类创建之后,被@Inject注解的方法也会依次执行。

        XXcomponents对应会自动编生成DaggerXXComponent,这才是创建和提供注入的实际操作。 一般会有Scope限定符号注释的component和provide,实现缓存类似单例的效果。
      • f3f4672ef98e:检验真理的唯一标准是:理论联系实际。一路过来,学到不少,现在就差实践中去使用了
      • 北爱歌:一口气读完了这个系列,非常好,通俗易懂~也是看了网上各种例子后依然云里雾里,从概念的角度学习 Dagger 才是正确的打开方式!👍
      • 10b100c4d903:helloworld
      • 欢乐的乐:感觉简书总是很多大神会很用心的写文章,谢谢你,终于理解dagger2了:yum:
      • HKers:楼主请问下之前已经编译好的daggercomponent没有报错,过段时间重新rebuild后,报找不到符号的错误是什么原因。
        牛晓伟:报什么错
      • 虞愚yu:三篇看完了,收获不少,写的很好。
      • WmIwd:看了一下demo,有一个地方不太懂,想请教一下:为什么需要这个ActivityModule 它里面提供了一个Activity,但是我看并没有地方用到这个Activity啊,因为其他module提供的实例都用地方用到,而这个provideActivity没有用到的地方,是否可以不需要这个ActivityModule呢?
        牛晓伟:@WmIwd 可以不需要,这个东西也没必要说是必须的
      • 平凡至简:网上找了N篇关于Dagger2的,还不如看完这个系列,谢谢楼主的付出和分享
      • vipheyue:还是没有讲明白Scope 😳
      • 天青色等煙雨_而我在等妳:求加好友,我加你了,你通过一下
      • cb3acfd2d88a:文章不错,可惜完全没有涉及到Dagger2的背后源码,而只是针对它帮我们生成的代码分析。如果能分析Dagger2的背后源码,对于AbstractProcessor一定会有更深入的理解。最近再看,发现源码有点复杂。
        牛晓伟: @binea 有时间希望能出源码文章
      • ml_bright:写的非常好
      • 8cd249b8ddf2:大神,我想问一下,dagger2里面的module提供的对象,如果构造函数需要参数,也需要在module里面提供,但是我查了好多例子,写的都是需要一些对象参数,如果我需要一些基本类型的参数呢?怎么穿进module里面? 例如我在activity里面注入了presenter,但是这个presenter我希望在其构造的时候,传入一些由intent从上个activity带过来的一些像userID这种的基本类型参数,请问怎么将这些动态的参数,传递到presenter中并参与构造?
        牛晓伟:@Beary 当然有方便new一个对象,主要是构造函数中有基本类型,string的话,处理起来会麻烦
        8cd249b8ddf2:@牛晓伟 所以dagger2只是方便项目中一个大的模块注入使用,并不是为了方便不用 "new" 一个对象?
        牛晓伟:@Beary 这种最好通过set方法来设置,用dagger做反而做复杂了
      • 任重道远学无止境:刚接触dagger,看来十来篇关于dagger的文章,只有这篇终于看懂了,非常感谢
      • _ERROR:Demo里各种Component和Module漫天飞舞,看的眼花缭乱啊 * _ *
        _ERROR:@_ERROR 比如MainComponent又是继承ActivityComponent又是dependencies那个AppComponent,这两种方式(dependencies和继承)有什么区别呢,继承是有了父类的方法,dependencies是有了那个类的引用还是怎么啊,这里不讲清楚还是看不懂呢* _ *
      • 凌言落雪:学到了,很感谢大神的分享
      • iceman_dev:看了那么多,这是最清晰的了
      • 沉重包袱一生:介绍Dagger2的文章,容易理解,看了,觉得入门了。
      • Koterwong:大神好厉害,么么哒~
      • 53c97f794edc:问一下楼主,@inject修饰成员方法的时候怎么用,怎么理解,这个系列的文章里好像没有说到。google的demo中有,理解起来好麻烦!
      • Neogx:感谢,Dagger2折腾了好长时间,这个系列让明白好多,剩下来的就是代码实践了··
      • 程序员Anthony:niubility :smile: 之前写过一篇文章,现在回来看你的文章,感觉对Dagger2的理解更进一步了。
      • _SOLID: 牛哥这个系列的文章太牛逼了!
        牛晓伟: @_SOLID 多谢
      • 键盘走过的日子:大神,我想问一下App层次的Module、Component是怎么和Activity层次的Module、Component怎么产生联系的。刚转到Android,Java都没学多少,求大神指点。。。。
        牛晓伟:@键盘走过的日子 原理就是dagger会寻找每个component的注解,发现没有或不一致报错
        键盘走过的日子:问题解决了。但是我想问一下在activity层的Componet在依赖App层的Component的时候,必须要加上一个自定义的scope以保证与其他的activity的生命周期一样,能不能给我讲一下这是什么原理啊??、
        牛晓伟:@键盘走过的日子 activity层次的Component会依赖app层次的component
      • idioitcbear:然后我有个问题,就是在Component在build的时候,会有依赖一些module的实例,这些module的实例在什么配置的情况加需要我们自己传进去,什么情况下他会帮忙new出来。就像下面这段代码:
        public MainComponent build() {
        if (mainModule == null) {
        this.mainModule = new MainModule();
        }
        if (activityModule == null) {
        throw new IllegalStateException("activityModule must be set");
        }
        if (appComponent == null) {
        throw new IllegalStateException("appComponent must be set");
        }
        return new DaggerMainComponent(this);
        }
        恁月:@想你0开心 在吗,我想问一下DaggerMainComponent,这个类,在components包里并没有啊,缺少,build时变红啊,
        还有就是我的External Libraries一大堆的play-serverces的库,是不是我的studio的问题,怎么会下载那么多
        idioitcbear:@牛晓伟 嗯,这个就是来自你的demo呀,就是想知道有些module可以不用传进去,有的module就必须传进去。是因为不用传module的时候,这个module是没有带有有参的构造函数么?
        还一个问题就是定义的这个接口,Component,在这里面申明的方法有什么用。
        //对MainActivity进行依赖注入
        void inject(MainActivity mainActivity);
        MainFragmentComponent mainFragmentComponent();
        这里面的方法有的有返回值有的没有返回值。
        当Component build出来以后,这个Component里面应该是有这些module对象的。这个inject方法是不是说明要注入到这个MainActivity。inject这个是固定写法么?下面这个mainFragmentComponent()方法是不是用了@subComponent修饰MainFragmentComponent,这样就能关联起来么?
        牛晓伟:@想你0开心 在写Component的时候,这时候需要配置Module,首先以dagger开头的类,是dagger自己生成的类,你只需要使用它们即可,在使用这些类时,需要传递的Moudle都会生成相应方法,下我的例子看看
      • idioitcbear:好厉害,解决很多疑惑,逻辑结构很清晰。。
      • 莫高窟同学:还能说啥,比起那些分析大堆无用代码,讲清楚思路还是最高水准!赞!
        牛晓伟: @Zihuatanejo50 谢谢
      • 8676c9c4894f:文章结构清晰,层层递进。解决了很多困惑。看到过的最好的介绍dagger2的中文文章,谢谢!
        牛晓伟: @longya3xian 多谢支持
      • miaoyongjun:非常不错 三篇看完了
      • 一斤十六两:http://ifarseer.github.io/2016/05/09/dagger2/,这篇是我分析Dagger2的一篇文章,欢迎帮我指正。
      • Champion是冠军:代码太少,需要结合实例才能看懂文章的意思
        JarvisGG:@Eric胡 试着敲一个完整的demo,踩踩坑就好了
      • Fritz_Xu:基础不好,demo看起来有点吃力;还得继续努力 :fist:
        牛晓伟: @武械 加我微信或qq细聊
        Fritz_Xu:敲完一半的代码编译通过后,再敲余下一半运行时,Android Studio提示DaggerAppComponent有illegalargumentexception异常,一开始都好好的,怎么分两次就不行了 :dizzy_face:
        牛晓伟: @武械 加油
      • binwin20:我下一个项目一定要用dagger。之前看了Android10的clean框架Demo,对何时使用perActivity这个域不是很懂。
        binwin20:@initialjie 没有,打算用谷歌的MVP,更简单。
        initialjie:@binwin20 你好,请问你们公司的项目开始使用了Android10的clean框架吗?实际效果如何?谢谢
        牛晓伟: @binwin20 可以用下,省好多事
      • 妙法莲花1234:trinea的同事吗,膜拜下大神
        牛晓伟:@追风917 不认识,滴滴太大了
        妙法莲花1234:@牛晓伟 ???不是吧?!

        https://github.com/Trinea

        你不认识?
        牛晓伟: @追风917 trinea是谁?不认识
      • 谈小龙:github项目缺少一个文件DaggerAppComponent
        牛晓伟: @谈小龙 哈哈
        谈小龙:太神奇了
        牛晓伟: @谈小龙 编译一下
      • 笨驴爱吃胡萝卜:写的很好,当初的同事,就知道必回成为一代牛人-----tongbin
        笨驴爱吃胡萝卜:@牛晓伟 我现在iOS和Android都要写,有空聊聊,求前辈带带路
        牛晓伟: @Tongbin 原来是佟斌啊

      本文标题:Android:dagger2让你爱不释手-终结篇

      本文链接:https://www.haomeiwen.com/subject/zstjlttx.html