• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • Dagger2分析學習

    Dagger學習筆記


    1.概要

    Dagger是為Android和Java平臺提供的一個完全靜態的,在編譯時進行依賴注入的框架,原來是由Square公司維護的然后現在把這堆東西扔給

    Google維護了

    控制反轉(Inversion of Control,縮寫Ioc),是面向對象編程中的一種設計原則,可以用來減少計算機代碼之間的耦合度,其中最常見的方式是依賴注入

    (Dependency Injection),還有一種叫做“依賴查找”(Dependency Lookup),通過控制反轉對象在創建的時候,有控制系統內所有對象的外界實體,將其

    所有依賴的對象的引用傳遞給它,也可以說,依賴注入到對象中。

    應用Dagger2的依賴庫:

    項目根目錄的配置文件中配置:

    buildscript {
    
        dependencies {
            classpath 'com.android.tools.build:gradle:2.2.2'
            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' (annotation processing tools)//注解處理工具
    	主要是用在java編譯的過程中解析java文件中的注解類型,從而產生代碼來替換掉源碼中的注解的功能。
        }
    }
    //應用apt插件
    apply plugin: 'com.neenbedankt.android-apt'
    dependencies {
        compile 'com.google.dagger:dagger:2.4'
        apt 'com.google.dagger:dagger-compiler:2.4'
        provided 'org.glassfish:javax.annotation:10.0-b28'
    }

    依賴注入的三種方式:

    public class CoffeeMachinWithInjection implements InjectMaker{
        private CoffeeMaker maker;
    
        /*依賴注入的3種常見形式
         *No.1  構造函數注入
         */
        public CoffeeMachinWithInjection(CoffeeMaker maker){
            this.maker = maker;
        }
    
        //No.2  Setter注入
        public void setMaker(CoffeeMaker maker){
            this.maker = maker;
        }
    
        // //No.3 接口注入
        @Override
        public void injectMaker(CoffeeMaker maker) {
            this.maker = maker;
        }
    
        public String makeCoffee(){
            return maker.makeCoffee();
        }
    
    }
    上述的表示中我們在平時的代碼開發中常使用到的代碼開發方式,手動提供注入,解決了使用在類內部使用時new一個新的對象。下面我們看是來對

    Dagger2進一步使用講解。動態的解決掉依賴注入。

    在Dagger中我們有六種注解:

    1.Inject:兩個作用

    1.在宿主中表明需要注入的類

    2.在需要實例化的類中的構造方法上使用,表明需要注解(沒有構造參數的類上號使用,在有構造參數的類中需要使用在module中使用@provides提供)

    2.Component:主要是在產生依賴的類之間生成通信的橋梁

    3.module:專門用來提供依賴

    4.provides:用來在module中專門提供產生依賴的類,主要用來標記提供依賴的方法


    這里再說明一個問題,我們有兩種方式可以提供依賴,一個是注解了@Inject的構造方法,一個是在Module里提供的依賴,那么Dagger2是怎么選擇依賴提供的呢,規則是這樣的:

    • 步驟1:查找Module中是否存在創建該類的方法。
    • 步驟2:若存在創建類方法,查看該方法是否存在參數
    • 步驟2.1:若存在參數,則按從步驟1開始依次初始化每個參數
    • 步驟2.2:若不存在參數,則直接初始化該類實例,一次依賴注入到此結束
    • 步驟3:若不存在創建類方法,則查找Inject注解的構造函數,看構造函數是否存在參數

    由上面的步驟可以看出使用依賴Dagger2時,先查找module中是否提供依賴注入對象,如沒有在使用構造方法來新建一個類



    2.dagger2調用過程


    dagger2的調用流程如上圖所示:

    Dagger2有三個構建組成:從上到下依次為:

    1.依賴需求方(宿主),需要使用對象實例的類。

    2.依賴提供方,統一提供實例類型或數據掉用的類。

    3.依賴注入構件(Component),負責管理module產生的數據注入到宿主中,在編程中表現為一個接口,編譯時apt自動回生成一個以Dagger開頭的類。

    上圖中從上到下依次對應上述的三個部分。下面先分析上面代碼的表現形式:

    在Activity中得到LoginActivityComponont:

    DaggerLoginActivityComponont.builder()
                    .appComponent(AppGlobalState.getInstances().getComponent())
                    .loginModule(new LoginModule(this, this))
                    .volidateModule(new VolidateModule())
                    .build()
                    .inject(this);
    LoginActivity中使用inject(this)方法來獲取建立與依賴注解類相關聯。

    先查看一下LoginActivityComponont類的實現:

    /**
     * Created by cangck on 17/5/19.
     */
    @MainActivityScope
    @Component(modules = {LoginModule.class, VolidateModule.class}, dependencies = AppComponent.class)
    public interface LoginActivityComponont {
    
        LoginActivity inject(LoginActivity activity);
    }

    在這個類中我們使用到了的注解說明:@MainActivityScope

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

    @scope又是Dagger2的一個域修飾符,對對象提供的范圍的一個限制

    @Target(ANNOTATION_TYPE)
    @Retention(RUNTIME)
    @Documented
    public @interface Scope {}
    
    @Singleton實例表示時,單例返回
    @Module
    public class AppModule {
        private Application mApplication;
    
        public AppModule(Application application) {
            this.mApplication = application;
        }
    
        @Singleton
        @Provides
        public Application provideApplication() {
            return mApplication;
        }
    }
    

    LoginModule的實現

    @Module
    public class LoginModule {
        private LoginActivity mActivity;
        private ILoginView mLoginView;
    
        public LoginModule(LoginActivity activity, ILoginView loginView) {
            this.mActivity = activity;
            this.mLoginView = loginView;
        }
    
        @Provides
        public LoginActivity providesActivity() {
            return mActivity;
        }
    
        @Provides
        public ILoginView proivdeLoginView() {
            return mLoginView;
        }
    
        @MainActivityScope
        @Provides
        public LoginUserBean getUserData() {
            LoginUserBean userBean = new LoginUserBean();
            userBean.setName("cck");
            userBean.setAge(20);
            return userBean;
        }
    
        @Provides
        public LoginPresenter provideLoginPresenter(LoginActivity activity, ILoginView loginView) {
            LoginPresenter presenter = new LoginPresenter(activity, loginView);
            return presenter;
        }
    }

    @MainActivityScope這個注解是對@Scope的擴展,表示只用在Component組件上使用@MainActivityScope注解是才能調用getUserData方法

    • component 的 inject 函數不要聲明基類參數;
    • Scope 注解必須用在 module 的 provide 方法上,否則并不能達到局部單例的效果;
    • 如果 module 的 provide 方法使用了 scope 注解,那么 component 就必須使用同一個注解,否則編譯會失敗;
    • 如果 module 的 provide 方法沒有使用 scope 注解,那么 component 和 module 是否加注解都無關緊要,可以通過編譯,但是沒有局部單例效果;
    • 對于直接使用 @Inject 構造函數的依賴,如果把 scope 注解放到它的類上,而不是構造函數上,就能達到局部單例的效果了;

    @Provides
        public ILoginView proivdeLoginView() {
            return mLoginView;
        }
    
        @Provides
        public LoginUserBean getUserData() {
            LoginUserBean userBean = new LoginUserBean();
            userBean.setName("cck");
            userBean.setAge(20);
            return userBean;
        }
    上面代碼中使用@provides注解方法,當調用對象時,注解工具會在在方法中查找使用@provides注解的方法,并且根據返回值來確認是通過那個方法來提供數據。

    注:方法的調用使用過返回值來確認的

    下列類為VolidateModule的實現

    /**
     * Created by cangck on 17/5/19.
     */
    
    @Module
    public class VolidateModule {
    }

    先列舉上面的兩個類來作為使用說明就Ok了

    我們先觀察一下LoginActivityComponont類上我們使用了注解

    @MainActivityScope
    @Component(modules = {LoginModule.class, VolidateModule.class}, dependencies = AppComponent.class)

    在上面已經介紹過了LoginActivityComponont類使用了注解@Component之后就好變成了Dagger2中的組件控制器。在觀察上圖,

    @Component的注解參數:1.modules,2.dependencies

    1.modules表示當前的Component管理LoginModule,VolidateModule,當需要使用類實例時當前的Component只能從上述的兩個類的范圍中來查找,不會到其他的類中去找。

    2.dependencies:相當于類的繼承關系,當前的Component不僅可以從自己管理的類中類獲取對象,亦可以使用AppComponent提供的方法來使用。

    Dagger2之間的三個組件關聯的方式已經介紹完成:

    1.LoginActivity中使用inject(this)的方法和Dagger2中的組件Component建立關系。

             2.Component與module建立聯系是通過@Component(moudel={aModule.class,BModule.class},dependecies=DComponent.class)
    4.Component的聲明周期:

    1.創建Component實例

     DaggerLoginActivityComponont.builder()
                    .appComponent(AppGlobalState.getInstances().getComponent())
                    .loginModule(new LoginModule(this, this))
                    .volidateModule(new VolidateModule())
                    .build()
                    .inject(this);

    1. onCreate()方法調用完成后,Component實例就會因為沒有被引用而被垃圾回收器回收.其中傳入給Component實例的Module實例也會一同被回收,這也就能說明不同的Component實例之間是沒有聯系的(Component依賴除外).這里需要注意的是,使用Lazy和Provider時,與該依賴對象有關的Module實例會被Lazy和Provider引用,所以該Module實例不會被垃圾回收器回收
    參考:

    Dagger2 入門,以初學者角度. Dagger2 入門,以初學者角度.

    依賴注入神器:Dagger2詳解系列

    圖文教程

    Android常用開源工具(2)-Dagger2進階

    Dagger2 Scope 注解能保證依賴在 component 生命周期內的單例性嗎?

    demo

    Android:dagger2讓你愛不釋手-重點概念講解、融合篇






    版權聲明:本文為cangck_x原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/cangck_x/article/details/72529160

    智能推薦

    dagger2的生成源碼簡單分析

    dagger2官方GitHub: 點擊打開鏈接 直接上圖,自己對dagger2構架的見解: 這里使用的是官方的實例分析的.  并稍微修改了CoffeeApp 然后生成 : CoffeeApp會被編譯器生成如下代碼: 這DaggerCoffeeApp的作用:對module,提供者和類注入器(現在還沒有)進行初始化,也是一個交互的場所. 然后根據module 提供的實例的方法生成&...

    Dagger2 Android依賴注入學習

    前言   最近在用 MVP + RxJava + Retrofit 寫項目,覺得相對于其他的開發框架,這的確是給我們帶來了很多方便,但是在網上搜尋相關資料的時候,總是能看到 MVP + RxJava + Retrofit + Dagger 這樣的搭配組合,那 Dagger 又是一個怎樣的框架呢,我也去具體搜了搜,但看到一些文章帶著“Dagger2從入門到放棄&rdq...

    安卓開發學習之Dagger2的使用

    今天閑來無事,就總結一下前些日子對Dagger2的學習使用 介紹 Dagger2是一個利用注解來構造類的實例的東西,網上稱此為依賴注入。 Dagger2主要有這么幾個注解@Inject、@Module、@Provides、@Component、@Qualifier和@Scope。在這篇文章中,我會為大家一一演示它們的簡單用法,供大家入門。 場景構造 我們先構造一個場景:咖啡店造咖啡   ...

    學習Dagger2筆記:【4】@Component

    目錄 0. 前言 1. 依賴與注入 2. @Inject 3. @Module & @Provides 4. @Component 5. @Qualifier 6. Provider & Lazy 7. @Scope 8. 注入到Set和Map容器 9. Bind系列注解 10. dagger中依賴關系與繼承關系 11. dagger.android 目標 上一篇說到我們想要dag...

    Dagger2使用詳解

    Dagger2 是一個Android依賴注入框架,由谷歌開發,最早的版本Dagger1 由Square公司開發。依賴注入框架主要用于模塊間解耦,提高代碼的健壯性和可維護性。 Dragger2 通過注解來生成代碼,定義不同的角色,主要的注解有:@Inject、@Module、@Component、@Provides、@Scope、@SubComponent等。 @Inject:通常在需要依賴的地方使...

    猜你喜歡

    Dagger2入門詳解

    Dagger2 確實比較難學,我想每個開發者學習的時候總是經歷了一番痛苦的掙扎過程,于是就有了所謂的從入門到放棄之類的玩笑,當然不排除基礎好的同學能夠一眼看穿。本文的目的嘗試用比較容易理解的角度去解釋 Dagger2 這樣東西。 Dagger2 是有門檻的,這樣不同水平能力的開發者去學習這一塊的時候,感受到的壓力是不一樣的。 我個人總結了大家在學習 Dagger2 時,為什么感覺難于理解的一些原因...

    快速入門Dagger2

    1、Dagger2的介紹和簡單使用: A fast dependency injector for Android and Java. 一個快速的依賴注入庫為java和android, 什么是依賴注入?有興趣的同學可以看一下我之前轉載的一篇依賴注入的文章。 https://github.com/google/dagger 這是Dagger2的github地址,里面介紹了在項目中如何使用和依賴。 1...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    精品国产乱码久久久久久蜜桃不卡