zoukankan      html  css  js  c++  java
  • android--------Dagger2介绍与简单使用(一)

    1:Dagger2是啥

    Dagger是为Android和Java平台提供的一个完全静态的,在编译时进行依赖注入的框架,原来是由Square公司维护的然后现在把这堆东西扔给Google维护了。

    一般的IOC框架都是通过反射来实现的,但Dagger2作为Android端的IOC框架,为了不影响性能,它是通过apt动态生成代码来实现的.

    Dagger2主要分为三个模块:

    1. 依赖提供方Module,负责提供依赖中所需要的对象,实际编码中类似于工厂类
    2. 依赖需求方实例,它声明依赖对象,它在实际编码中对应业务类,例如Activity,当你在Activity中需要某个对象时,你只要在其中声明就行,声明的方法在下面会讲到.
    3. 依赖注入组件Component,负责将对象注入到依赖需求方,它在实际编码中是一个接口,编译时Dagger2会自动为它生成一个实现类.


    Dagger2的主要工作流程分为以下几步:

    1. 将依赖需求方实例传入给Component实现类
    2. Component实现类根据依赖需求方实例中依赖声明,来确定该实例需要依赖哪些对象
    3. 确定依赖对象后,Component会在与自己关联的Module类中查找有没有提供这些依赖对象的方法,有的话就将Module类中提供的对象设置到依赖需求方实例中

    通俗上来讲就好比你现在需要一件衣服,自己做太麻烦了,你就去商店买,你跟商店老板说明你想要购买的类型后,商店老板就会在自己的衣服供应商中查找有没有你所说的类型,有就将它卖给你.其中你就对应上面所说的依赖需求方实例,你只要说明你需要什么,商店老板则对应Component实现类,负责满足别人的需求,而衣服供应商则对应Module类,他负责生产衣服.也许这里有点绕,但经过下面的Demo,也许能够帮助你理解.

    2:案例讲解

    在项目下的build.gradle文件中添加apt插件:

        dependencies {
            classpath 'com.android.tools.build:gradle:2.2.3'
            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }

    在app目录的build.gradle文件中添加:

        provided 'javax.annotation:javax.annotation-api:1.2'
        compile 'com.google.dagger:dagger:2.5'
        apt 'com.google.dagger:dagger-compiler:2.5'

    首先我们创建一个商品类

    /***
     * 这是一个商品类
     */
    public class CommodityInfo {
    
        @Inject
        public CommodityInfo (){
    
        }
    
        @Override
        public String toString() {
            return "我是商品类对象";
        }
    }

    我们在构造方法上面添加了一个@Inject注解,有啥用呢?

    我们使用ctrl+F9(mac使用Cmd+F9)进行一次编译,编译结束后,打开文件

     

    自动生成的代码:

    @Generated(
      value = "dagger.internal.codegen.ComponentProcessor",
      comments = "https://google.github.io/dagger"
    )
    public enum CommodityInfo_Factory implements Factory<CommodityInfo> {
      INSTANCE;
    
      @Override
      public CommodityInfo get() {
        return new CommodityInfo();
      }
    
      public static Factory<CommodityInfo> create() {
        return INSTANCE;
      }
    }

     创建一个Module类以及一个Component接口

    @Module  //这是一个提供数据的【模块】
    public class Demo1Module {
    
        private Demo1Activity demo1Activity;
    
        public Demo1Module (Demo1Activity activity){
            this.demo1Activity = activity;
        }
    
    }
    //这是一个【组件】/注射器
    @Component(modules = Demo1Module.class)
    public interface Demo1Component {
    
        //这个连接器要注入的对象。这个inject标注的意思是,我后面的参数对象里面有标注为@Inject的属性,
    //这个标注的属性是需要这个连接器注入进来的。
    void inject(Demo1Activity demo1Activity); }

    可以使用商品类对象了

    public class Demo1Activity extends AppCompatActivity {
    
        TextView textView;
    
        @Inject
        CommodityInfo commodityInfo;
    
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.demo1_layout);
            DaggerDemo1Component.builder()
                    //.demo1Module(new Demo1Module(this)) //可要可不要
            .build().inject(this);
            initView();
        }
    
    
        private void initView(){
            textView = (TextView) findViewById(R.id.textView);
            findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(Demo1Activity.this,"对象值:"+commodityInfo.toString(),Toast.LENGTH_LONG).show();
                    textView.setText("对象值:"+commodityInfo.toString());
                }
            });
        }
    }

    3:简单介绍

    我们假设案例中的Activity代表家庭住址,CommodityInfo代表某个商品,现在我们需要在家(Activity)中使用商品(CommodityInfo),我们网购下单,商家(代表着案例中自动生成的CommodityInfo_Factory工厂类)将商品出厂,这时我们能够在家直接获得并使用商品吗?

    当然不可能,虽然商品(CommodityInfo)已经从工厂(Factory)生产出来,但是并没有和家(Activity)建立连接,我们还需要一个新的对象将商品送货上门,这种英雄级的人物叫做——快递员(Component,注入器)。

     没错,我们需要这样的一种注入器,将已经生产的Student对象传递到需要使用该Component的容器Activity中,于是我们需要在Activity中增加这样几行代码:

    DaggerDemo1Component.builder().demo1Module(new Demo1Module(this)).build().inject(this);

    这就说明快递员Component已经将对象Inject(注入)到了this(Activity)中了,既然快递到家,我们当然可以直接使用CommodityInfo啦!

    @Inject : 注入,被注解的构造方法会自动编译生成一个Factory工厂类提供该类对象。
    
    @Component: 注入器,类似快递员,作用是将产生的对象注入到需要对象的容器中,供容器使用。
    
    @Module: 模块,类似快递箱子,在Component接口中通过@Component(modules = 
    xxxx.class),将容器需要的商品封装起来,统一交给快递员(Component),让快递员统一送到目标容器中。
    效果如图:
     
                
     
     
     
  • 相关阅读:
    一起谈.NET技术,.NET分布式架构开发实战之一 故事起源 狼人:
    JS替换节点
    mysql数据库的简单语句的介绍(1)
    JS对img进行操作
    POJ 1006 Biorhythms 数论(孙子定理)
    Tomcat与Jetty插件 配置根路径指定项目
    [置顶] cocos2dx 2.x版本之win32 window移植android 环境搭配 只用NDK 超级详细 android 环境搭配
    调频广播六十年
    ajax两个网页实现完美的 分页功能
    Cocos2dX数据、动作、消息的基本操作
  • 原文地址:https://www.cnblogs.com/zhangqie/p/8540680.html
Copyright © 2011-2022 走看看