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

        爲了介紹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());
        }
        其結果如下圖所示:
        


二、最簡單的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如下:
        
        這說明我們已經可以使用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,運行結果是這樣的:
        


四、一個疑問

        上面的例子雖然介紹了有參數和無參數的注入,但他們都有兩個侷限:
        1、需要修改構造方法,添加@Inject的標識,但是對於一些jar包中的方法,或者第三方API中提供的方法,我們無法修改其源碼
        2、雖然構造方法中可以傳遞參數,但是實際上對這個參數也是有要求的,這個參數雖然會遞歸創建,但遞歸的最後一層的構造方法中還是無法傳參的
        要解決這兩個問題,請繼續看下一篇《Dagger2教程三之構造方法帶參數的情況(原)》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章