android--------Dagger2介绍与简单使用(一)

摘要:
voidinject;}您可以使用商品类对象publicclassDemo1ActivityextendsAppCompatActivity{TextViewtextView;@InjectCommodityInfocommodityInfo;@OverrideprotectedvotionCreate{super.onCreate;setContentView;DaggerDemo1Component.builder()//.demo1Module//如果需要,请不要使用.build().object;initView();}privatevoidinitView((){textView=findViewById;findViewById.setOnClickListener;}}3:简要介绍我们的假设,即案例中的活动代表家庭地址,CommodityInfo代表产品。现在我们需要在家里使用该产品。我们在线订购,商家离开工厂。我们可以在家直接获得和使用产品吗?

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)进行一次编译,编译结束后,打开文件

  android--------Dagger2介绍与简单使用(一)第1张

自动生成的代码:

@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),让快递员统一送到目标容器中。
效果如图:
 
             android--------Dagger2介绍与简单使用(一)第2张
 
 
 

免责声明:文章转载自《android--------Dagger2介绍与简单使用(一)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Python调用百度OCR识别API实现文字图片识别C# 固定窗体大小且不能鼠标调整大小完美实现下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Android中Handler的使用

当我们在处理下载或是其他需要长时间执行的任务时,如果直接把处理函数放Activity的OnCreate或是OnStart中,会导致执行过程中整个Activity无响应,如果时间过长,程序还会挂掉。Handler就是把这些功能放到一个单独的线程里执行,与Activity互不影响。 import android.app.Activity;import an...

Android去掉标题,强制设置横屏或竖屏(转载)

全屏在Activity的onCreate方法中的setContentView(myview)调用之前添加下面代码 requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, Win...

Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误

嵌套Fragment的使用及常见错误 嵌套Fragments (Nested Fragments), 是在Fragment内部又添加Fragment. 使用时, 主要要依靠宿主Fragment的 getChildFragmentManager() 来获取FragmentManger. 虽然看起来和在activity中添加fragment差不多, 但因为f...

Android Tv 中的按键事件 KeyEvent 分发处理流程

本篇文章已授权微信公众号 安卓巴士Android开发者门户 独家发布 这次打算来梳理一下 Android Tv 中的按键点击事件 KeyEvent 的分发处理流程。一谈到点击事件机制,网上资料已经非常齐全了,像什么分发、拦截、处理三大流程啊;或者 dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent 啊...

安卓开发之activity详解(sumzom)

    app中,一个activity通常是指的一个单独的屏幕,相当于网站里面的一个网页,它是对用户可见的,它上面可以显示一些控件,并且可以监听处理用户的时间做出响应。        那么activity之间如何进行通信呢?他们是通过intent进行通信以及切换。Intent有两个重要部分(动作传递,数据传递); Ø神马是Activity?     act...

Android框架式编程之BufferKnife

BufferKnife作为框架式编程的重要组成部分,使用BufferKnife能够极大的精简View层面的代码量,并为MVP/MVC方式提供辅助。 一、配置 compile 'com.jakewharton:butterknife:(insert latest version)' annotationProcessor 'com.jakewharton:...