Dagger2教程二之基础使用(原)

Dagger2教程二之基础使用(原)为了介绍Dagger2的使用,我们搭建了一个Demo来逐步分析,大家可以在这里下载源码(https://github.com/dushaofeng/DaggerDemo.git)。    上一节我们介绍了《Dagger2教程一之配置篇》,这一节我们来介绍Dagger2的具体使用方法。一、原始方式    我们先来看一下如果不使用Dagger的情况,我们在Activ

大家好,欢迎来到IT知识分享网。        为了介绍Dagger2的使用,我们搭建了一个Demo来逐步分析,大家可以在这里
下载源码(https://github.com/dushaofeng/DaggerDemo.git)。

        上一节我们介绍了
Dagger2教程一之配置(原),这一节我们来介绍Dagger2的具体使用方法。

一、原始方式

        我们先来看一下如果不使用Dagger的情况,我们在Activity中创建一个Bean的对象,其构造方法无需传递任何参数,但是内部会初始化其成员name,然后在Activity中使用该对象。

        Bean的内容为:

        public class Bean {
            private String mName = null;


            public Bean() {
                this.mName = "原始方式";
            }


            public String getName() {
                return mName;
            }
        }

        在Activity中创建并使用该对象:

        private void testOrignal() {
            Bean bean = new Bean();
            Log.d(TAG, "不使用Dagger时 Name:" + bean.getName());
        }

        其结果如下图所示:

        
Dagger2教程二之基础使用(原)

二、最简单的Dagger使用方式

        接下来我们通过一个例子来介绍如何通过Dagger来实现上面的代码。

2.1、改造Bean

        和Bean类似,我们新建一个BeanForDagger的对象,其内容为:

        public class BeanForDagger {
            private String mName = null;


            @Inject
            public BeanForDagger() {
                this.mName = "Dagger方式";
            }


            public String getName() {
                return mName;
            }
        }

        这个BeanForDagger和Bean的区别有两点:

        1、mName的初始化名称不同,这是为了区分两个对象

        2、BeanForDagger的构造方法多了@Inject的注释,它会告诉Dagger用这个方法来注入目标类

2.2、创建Component文件

        然后我们我们新建一个BeanComponent的接口(文件),其内容如下:

        @Component
        public interface BeanComponent {
            void inject(MainActivity activity);
        }

        请注意,这个接口使用了@Component的注释。

2.3、使用Dagger

        经过上面修改之后,我们就可以使用Dagger来自动创建BeanForDagger对象了。

        首先在Activity中声明该变量:

        @Inject
        BeanForDagger mBeanForDagger;

        然后我们可以这样使用该变量:

        private void testDagger() {
            // 触发Dagger机制
            DaggerBeanComponent.create().inject(this);
            if (mBeanForDagger != null) {
                Log.d(TAG, "使用Dagger注入变量,mBeanForDagger Name:" + mBeanForDagger.getName());
            }
        }

        运行之后的Log如下:

        
Dagger2教程二之基础使用(原)

        这说明我们已经可以使用mBeanForDagger了,但是请注意,在Activity中(以及BeanComponent或BeanForDagger中),我们并没有创建(new)BeanForDagger的对象。

        也就是说,Dagger帮助我们完成了创建BeanForDagger对象的工作

2.4、Dagger创建对象的过程

        这一节我们通过最简单的描述来简单介绍一下Dagger是如何帮助我们创建BeanForDagger对象的。

        首先,在Activity的testDagger方法中,多了这么一句:

            DaggerBeanComponent.create().inject(this);

        而这里的DaggerBeanComponent是Dagger根据BeanComponent自动生成的,
每一个XXXComponent都会生成对应的DaggerXXXComponent文件

        当调用inject()时,DaggerBeanComponent就会扫描inject方法中的参数(当前就是Activity)中
用@Inject标记的变量,对于当前的Activity来说,只有mBeanForDagger变量被标记。

        找到这个需要被注入的变量后,发现他的类型是BeanForDagger,接下来,Dagger就会去搜索BeanForDagger的类,然后找到该类中
用@Inject标记的构造方法,并用该构造方法来创建对象。

        这个过程简单来说就是这个步骤:

        1、通过DaggerXXXComponent的Inject()触发注入过程

        2、搜索目标类中用@Inject标识的需要注入的对象

        3、找到需要注入对象后,寻找该对象中用@Inject标识的构造方法,完成自动创建过程

2.5、用到的注释

        截至目前,我们用到了两个注释:
@Inject和@Component,其中的Inject用来注释需要注入的目标对象,以及用来注入的构造方法,而Component用来触发注入机制。

三、带参数的构造方法

        上面的使用过程虽然简单,但是他的特点很明显:
需要被注入的对象的构造方法无需传参数!

        因为无需传参,所以Dagger找到该构造方法后可以使用new BeanForDagger()的方法来完成创建工作。

        那么疑问就来了,如果这个构造方法需要参数时,怎么办?Dagger是否具有创建参数的能力?

        比如我们的BeanForDagger对象的构造方法是这样的:

        @Inject
        public BeanForDagger(ParamForDagger param) {
            this.mName = param.mParamName;
        }

        那么Dagger如何才能获得ParamForDagger的参数呢?

        解决的方法很简单,只需要
在ParamForDagger的构造方法中标记@Inject即可,如这样:

        public class ParamForDagger {
            String mParamName = null;


            @Inject
            public ParamForDagger() {
                mParamName = "ParamName";
            }
        }

        这样一来,当Dagger在创建BeanForDagger时发现其构造方法需要ParamForDagger的对象,那么Dagger就会
递归查找ParamForDagger类中使用Inject标记的构造方法,找到后,先创建ParamForDagger,然后再用他来创建BeanForDagger。

        也就是说,
Dagger具备递归创建对象的能力。

        这个例子执行结果就是,将BeanForDagger中的mName初始化为ParamForDagger中的值:ParamName,运行结果是这样的:

        
Dagger2教程二之基础使用(原)

四、一个疑问

        上面的例子虽然介绍了有参数和无参数的注入,但他们都有两个局限:

        1、需要修改构造方法,添加@Inject的标识,但是对于一些jar包中的方法,或者第三方API中提供的方法,
我们无法修改其源码

        2、虽然构造方法中可以传递参数,但是实际上对这个参数也是有要求的,这个参数虽然会递归创建,
但递归的最后一层的构造方法中还是无法传参的

        要解决这两个问题,请继续看下一篇
《Dagger2教程三之构造方法带参数的情况(原)》

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/15937.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信