美文网首页
Dagger2入门!精通!最美!死神的力量!

Dagger2入门!精通!最美!死神的力量!

作者: 大锅饭_ | 来源:发表于2017-12-07 23:54 被阅读0次

    1、说在前面

    如果你是做Android开发的,写代码家常便饭,随着时间消逝,自己也成长不少,会遇到(前方超大字体预警)
    代码耦合、团队协作冲突解决,类依赖复杂度等诸多问题,如何解决,使队友之间的不在冲突,来一波nice助攻,Dagger2,MVP是你的选择。(打广告重大嫌疑),也有不足之处,就是会写很多类和接口,也能理解嘛,解耦必然会增加文件的数量(后面将会封装模板一键生成相关类敬请期待)---严博


    dagger2使用大项目的开发,减少依赖实现解耦,小项目就用不上了,因为他会写很多接口和类,但是当你做大项目的时候就会体现他的好处不是一点点

    2、为什么使用Dagger2它能干什么

    前面我们只是简单介绍了一下Dagger2的基本认识接下来我们进入主题,讲讲,Dagger2能做什么


    做项目时,常需在一个对象里去创建另一个对象的实例,这种行为是产生耦合的常见形式。大项目来说过多的项目依赖会导致代码难以维护。
    列子说话

    /**
         * 有一男孩班级类中new出,此类一run方法调用男孩的run方法
         一个对象里通过new 创建另一个对象-->产生耦合常见形式,
         */
        public class Classes {
            // 依赖类
            private Boy boy;
            public Classes(){
                // 在当前对象中直接 new 出依赖类
                boy = new Boy();
            }
            public void run(){
                boy.run();
            }
        }
    

    此时看桌无大碍,那么boy发生变化,其构造方法发生变化,需要传一个姓名需要修改代码

        public class Boy {
            String name;
            //原来的构造方法修改如下
            /*public Boy(){
            }*/
            public Boy(String name ){
                // 修改了构造方法
                this.name = name;
            }
            public void run(){
    
            }
        }
    
    public class Classes {
        // 依赖类
        private Boy boy;
        public Classes(){
            //  因为Boy的构造方法发生变化,所以需要修改该处代码
            boy = new Boy("lilei");
        }
        public void run(){
            boy.run();
        }
    
    }
    

    可见:若boy变化,其构造方法发生变化,需传一姓名,需修改代码
    修改了Boy的构造方法之后,因为Classes依赖Boy,所以其内部也需要修改。
    如果又发生了变化,Boy的姓名更改了,又要修改Classes中的代码。。。这样的话,一个还是不明显,当工程量很浩大时,呵呵了。
    所以我们寻求一种方法,只关注怎么实现功能,对象的依赖关系和生命周期都让它来管理,一个Inject,它会按照依赖关系帮我们注入我们需要的对象,并且它会管理好每个对象的生命周期,在生命周期还没结束的情况下是不会重复new的、这就是Dagger2的用途。

    图解一下有点丑理解一下,(纯手工打造)

    这里写图片描述

    下面我们将带领大家开启dagger2的使用之路

    Dagger2在studio中的配置

    studio3.0之前的配置方法

    • app的gradle

    最上面应用apt插件

    apply plugin: 'com.neenbedankt.android-apt'
    
    • dependencies里
    // dagger 2 的配置
        compile 'com.google.dagger:dagger:2.4'
        apt 'com.google.dagger:dagger-compiler:2.4'
        compile 'org.glassfish:javax.annotation:10.0-b28'// 添加java 注解库
    
    • 工程gradle
    buildscript {
        dependencies {
            classpath 'com.android.tools.build:gradle:2.1.0'
            // 添加android-apt 插件
            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        }
    }
    

    android-apt,是Gradle编译器的插件,目的:

    • 编译时使用该工具,最终打包时不会将该插件打入到apk中。
    • 能够根据设置的源路径,在编译时期生成相应代码。

    studio3.0配置

    比较简单

    app gradle中

    mplementation 'com.google.dagger:dagger:2.11'
    implementation'com.google.dagger:dagger-compiler:2.11'
    
    

    配置结束开始使用

    四个基础

    我们还是用图解一哈

    这里写图片描述

    dagger2注入步骤

    • 1、看Module中是否存在创建该类的方法
    • 2、存在创建该类的方法-->再看方法是否存在参数
    • 2.1、存在参数-->按步骤1开始依次初始化每个参数(就是在获取该类实例的过程中还有其他实例需要获取同样方法获取)
    • 2.2、不存在参数-->直接初始化该类实例。一次依赖注入到此结束
    • 3、不存在创建该类的方法-->找Inject注解的构造函数,看构造函数是否有参数
    • 3.1、有,从步骤1开始依次初始化每个参数
    • 3.2、不存在,则直接初始化该类实例,依次依赖注入到此结束、。

    其他注解

    @Qulifier

    在Module里方法命名怎样都行,一般以provide+..命名,因为他是根据返回类型来确定的。不管你方法名是什么,如果返回值一样那用谁呢----依赖迷失--->用@Qulifier

    列子

    • 定义了两个注解,@A和@B,他们都是用@Qulifiier标注的
    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    public @interface A {}
    
    
    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    public @interface B {}
    
    • Module
    @Module
    public class SimpleModule {
    
        @Provides
        @A
        Cooker provideCookerA(){
            return new Cooker("James","Espresso");
        }
    
    
        @Provides
        @B
        Cooker provideCookerB(){
            return new Cooker("Karry","Machiato");
        }
    
    }
    
    • 使用
    public class ComplexMaker implements CoffeeMaker {
        Cooker cookerA;
        Cooker cookerB;
    
        @Inject
        public ComplexMaker(@A Cooker cookerA,@B Cooker cookerB){
            this.cookerA = cookerA;
            this.cookerB = cookerB;
        }
    
        @Override
        public String makeCoffee() {
            return cooker.make();
        }
    }
    
    
    cookerA.make();//James make Espresso
    cookerB.make();//Karry make Machiato
    

    @Scope

    一个Scope注解

    @Scope
    @Retention(RetentionPolicy.RUNTIME)
    public @interface PerActivity {}
    

    我们把定义的@PerActivity用到Module里

    @Module
    public class ActivityModule {
    
        @Provides
        CoffeeShop provideCoffeeShop(){
            return CoffeeShop.getInstance();
        }
    
        @Provides
        @PerActivity
        CookerFactory provideCookerFactory(){
            return new CookerFactory();
        }
    
        @Provides
        CookerFactoryMulty provideCookerFactoryMulty(){
            return new CookerFactoryMulty();
        }
    }
    

    相关文章

      网友评论

          本文标题:Dagger2入门!精通!最美!死神的力量!

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