1. 程式人生 > >深入淺出,一篇文章讓你學會使用Dagger2

深入淺出,一篇文章讓你學會使用Dagger2


今日科技快訊

近日,GitHub遭遇史上最大規模DDoS攻擊,每秒1.35TB的流量瞬間衝擊了這一開發者平臺。GitHub試圖反抗,但不到10分鐘,它就自動要求安全公司Akamai Prolexic提供幫助。這家專門減輕 DDoS 攻擊的公司接管了 GitHub 的所有流量。它的伺服器能夠承受比普通站點大得多的流量,通過其清理中心傳送資料以清除和阻止惡意資料包。這並不是第一次針對GitHub的重大DDoS攻擊,該平臺曾在2015年3月面臨六天的衝擊。

作者簡介

大家週一好,經過了元宵節的調整之後,將精力重新投入到工作中吧。

本篇來自  志先生_ 的投稿,分享了 Dagger2 的使用 ,一起來看看!希望大家喜歡。


 志先生_ 的部落格地址:

http://blog.csdn.net/gg199402

前言

最近在做專案中,用到了 Dagger2,所以找了一些部落格並參考了菜鳥窩 Ivan 的視訊,算是知道如何使用了,但是對其理解還相差很遠。所以這篇文章重點針對如何使用和使用中常見的一些問題。

Dagger2

根據官網來說他就是一個快速的依賴注入框架。如果對依賴注入不太瞭解,那麼請自行搜尋依賴注入原理,在這裡我就不過多介紹了。其實他的作用重點就是解耦和管理例項物件。那我們看看他具體有什麼好處:

  1. 依賴的注入和配置獨立於元件之外,注入的物件在一個獨立、不耦合的地方初始化,這樣在改變注入物件時,我們只需要修改物件的實現方法,而不用大改程式碼庫。

  2. 依賴可以注入到一個元件中:我們可以注入這些依賴的模擬實現,這樣使得測試更加簡單。

  3. app 中的元件不需要知道有關例項建立和生命週期的任何事情,這些由我們的依賴注入框架管理的

這是網上的一切說法。對於文字我們不好理解,還是看看在具體應用中我們該如何去使用。不過在使用之前我們先簡單的理解及概念。 

  • @Inject

通常在需要依賴的地方使用這個註解。換句話說,你用它告訴 Dagger 這個類或者欄位需要依賴注入。這樣,Dagger 就會構造一個這個類的例項並滿足他們的依賴。

  • @Module

Modules 類裡面的方法專門提供依賴,所以我們定義一個類,用@Module 註解,這樣 Dagger 在構造類的例項時候,就知道從哪裡去找到需要的依賴。modules 的一個重要特徵是它們設計為分割槽並組合在一起(比如說,我們的 app 中可以有多個組成在一起的modules)

  • @Provide

在 modules 中,我們定義的方法是用這個註解,以此來告訴 Dagger 我們想要構造物件並提供這些依賴。

  • @Component

Components 從根本上來說就是一個注入器,也可以說是@Inject 和@Module 的橋樑,它的主要作用就是連線這兩個部分。 

讀不懂也沒關係,我們接下來實戰程式碼。在講解後在結合概念我們就能很好的理解了。

 引入

引入方法有2種: 

第一種

在工程的 build.gradle 檔案中新增 android-apt 外掛(該外掛後面介紹)

buildscript {

   ....

   dependencies {

       classpath 'com.android.tools.build:gradle:2.1.0'
       // 新增android-apt 外掛
       classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
   }
}

在 app 的中的 build.gradle 檔案中新增配置

apply plugin: 'com.android.application'
// 應用外掛
apply plugin: 'com.neenbedankt.android-apt'

android {
   compileSdkVersion 23
   buildToolsVersion "23.0.2"

   defaultConfig {
       applicationId "com.mahao.alex.architecture"
       minSdkVersion 15
       targetSdkVersion 23
       versionCode 1
       versionName "1.0"
   }
   buildTypes {
       release {
           minifyEnabled false
           proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
       }
   }
}


dependencies
{
   compile fileTree(dir: 'libs', include: ['*.jar'])
   testCompile 'junit:junit:4.12'
   compile 'com.android.support:appcompat-v7:23.3.0'

   // dagger 2 的配置
   compile 'com.google.dagger:dagger:2.4'
   apt 'com.google.dagger:dagger-compiler:2.4'
   compile 'org.glassfish:javax.annotation:10.0-b28'// 新增java 註解庫
}

以上兩個配置就可以了。

android-apt 是 Gradle 編譯器的外掛,根據其官方文件,主要兩個目的:

  • 編譯時使用該工具,最終打包時不會將該外掛打入到 apk 中。

  • 能夠根據設定的源路徑,在編譯時期生成相應程式碼。

在匯入類庫時,

compile 'com.google.dagger:dagger:2.4'
apt 'com.google.dagger:dagger-compiler:2.4'

dagger是主要的工具類庫。dagger-compiler為編譯時期生成程式碼等相關的類庫。

在android-apt的文件中,也推薦使用這種方式。因為,編譯時期生成程式碼的類庫在執行期並不需要,那麼將其分為兩個庫,(執行類庫 dagger )和(編譯器生成程式碼類庫(dagger-compiler)),那麼在打包時,就不需要將 dagger-compiler 打入其中(用不到),減小 APK 的大小。

第二種

這種方法比較簡單(Android Studio2.2以上),直接引入依賴

 compile 'com.google.dagger:dagger:2.9'
annotationProcessor 'com.google.dagger:dagger-compiler:2.9'

我們這裡推薦第一種方式。

實踐(基本用法)
public class ApiService {

   public void register() {
       //註冊的方法
        Log.i("TAG", "ApiService: ");
   }

}

public class UserStroe {

   public void login(){
       //登入的方法
   }
}

首先假設我們現在有兩個方法,一個是註冊,另一個是登入。如果我們現在 MainActivity 中呼叫 register(); 我們一般會這麼寫:

ApiSeivie apiServce=new ApiService();
apiService.register();

如果們們使用Dagger2該如何使用呢? 

Module

首先:我們先建立module(他是主要提供例項的類),這裡我們定義為UserModule:

@Module
public class UserModule {

   public UserModule() {
   }

   @Provides
   public ApiService provideApiService() {
       return new ApiService();
   }
}
  • @Module

Modules 類裡面的方法專門提供依賴,所以我們定義一個類,用@Module 註解,這樣 Dagger 在構造類的例項時候,就知道從哪裡去找到需要的依賴。

  • @Provide

在modules中,我們定義的方法是用這個註解,以此來告訴Dagger我們想要構造物件並提供這些依賴。

現在我們回頭在看看概念是不就明白其中的含義了。

可以看到我們在 MainActivity 中需要 ApiService,我們在 module 中建立他的例項。等他需要的時候我們就給他。現在 module 建立好了。我們還需要呼叫者( MainActivity )和被呼叫者( module )之間的橋樑,這就是 Component。

注意,在 module 中,我們建立的方法必須是 public 不可以是 privite。這個也很好理解。我們建立的方法本來就是給外界呼叫的,如果你用 privite 的話只能本類使用了。
Component
@Component(modules = {UserModule.class})
public interface UserComponet {

   void inject(MainActivity activity);
}
注意:inject 方法接收父型別引數,而呼叫時傳入的是子型別物件則無法注入。比如你想作用 BaseActivity,inject() 就傳入 BaseActivity,但是隻能作用 BaseActivity 不能作用子類MainActivity。反之亦然;
  • @Component

我們定義 UserComponet 並加上@Component 註解。表明他是一個橋樑。首先他必須是一個介面。其次我們必須依賴一個 module(當然,從{}這個符號我們就可以看到,他可以同時依賴多個 module),它還有另一引數 dependencies,這裡我們先不說他,等後面講到了再說他。這裡我們看到他裡面只有一個方法 void inject()。這裡我們傳入 MainActivity,因為我們想在這個類中使用我們例項 ApiService。這樣 module 和 MainActivity 通過 Component 就關聯起來了。建立好這些類以後我們需要 Rebuild Progect。 

這是會生成一個 DaggerUserComponet 類,這個類命名是以 Dagger 開頭接上我們 UserComponet 類名。這個類方法很少,主要就是將我們的 MainActivity 和 Component 關聯起來,通過:

DaggerUserComponet.create().inject(this);

將我們的 MainActivity 傳入 Component 的 inject()方法中,這樣這個橋樑就就通了,我們就可以使用了,如下:

public class MainActivity extends AppCompatActivity {

   @Inject
   ApiService mApiService;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       DaggerUserComponet.create().inject(this);
       mApiService.register();
       Log.d("TAG", "onCreate: " + mApiService);
   }
}
注意 這裡我們 @Inject註解的物件不能用 privite 修飾。在我們的想要的建立的物件加上@Inject 註解並且呼叫 DaggerUserComponet.create().inject(this); 後我們就可以使用這個物件了。我們執行看看結果:
dagger2 D/TAG: ApiService: 
com.example.ggxiaozhi.dagger2 D/TAG: onCreate: [email protected]4a7c73b4

可以看到正常執行沒有問題了。例項物件已經被我們創建出來了。為們用2張圖總結一下: 

這張圖從概念出發,我們再從我們的例子中總結出來經驗概括就是這樣的:

明白了流程後那他是怎麼解耦的呢?使用方法就這麼簡單就結束了嗎?答案是肯定的。我們一定不止這麼簡單,關於解耦的話我就舉一個簡單的例子。之前我們建立了2個類註冊和登入,現在我們再建立一個類去管理他們:

public class UserManager {

   UserStroe mUserStroe;
   ApiService mApiService;

   public UserManager() {
       mApiService = new ApiService();
       mUserStroe = new UserStroe();
   }

   public void register() {
       mApiService.register();
       mUserStroe.login();
   }
}

然後我們在 MainActivity 中去呼叫 UserManager 中的 register 方法。這麼一個看好像是沒什麼問題,但是如果我們 mApiService.register(); 需要一個 Context 引數怎麼辦?你可能會這麼該:

public class UserManager {

   UserStroe mUserStroe;
   ApiService mApiService;

   public UserManager(Context context) {
       mApiService = new ApiService(context);
       mUserStroe = new UserStroe();
   }

   public void register() {
       mApiService.register();
       mUserStroe.login();
   }
}

呼叫處 new UserManager(this); 但是你注意看,我們只是需要一個 context 就要將 UserManager 和 MainActivity 中的程式碼都要改,要是在實際專案中,需要改更多的引數呢?所以我們來看下用 Dagger2 該如何解決。這裡我把需求再複雜話一些。首先我們還是先從module 來看: 這裡我們將例子複雜一下假設 ApiService 需要一個 context,userStroe 需要一個 url。我們就可以這樣寫

@Module
public class UserModule {

   Context context;

   public UserModule(Context context) {
       this.context = context;
   }

   @Provides
   public ApiService provideApiService() {
       return new ApiService(context);
   }
   @Provides
   public String

相關推薦

深入淺出文章學會Dagger2使用

本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出 前言 最近在做專案中,用到了Dagger2,所以找了一些部落格並參考了菜鳥窩Ivan的視訊,算是知道如何使用了,但是對其理解還相差很遠。所以這篇文章重點針對如何使用和使用中常見的一些問題

止損不見得能控制住回撤文章認清自己的止損!

結果 股票 部分 接下來 ESS 我希望 錯誤 占比 被套 首發:寬客在線 NO:01文字並不具備精確傳遞信息的能力。除了程序員和律師等少數群體,很少人能保證自己說的東西能在一句話中被清晰傳遞的。所以,帶著思考閱讀從而幫助完善你的知識體系,改變你的行為,這才是您耗費時間,閱

文章學會json和Gson---json全面詳細解析

現在企業越來越多的使用json返回資料,因此熟練使用json解析,是程式設計師必不可少的技能。 一、對json的理解 1)JSON(JavaScript Object Notation, js 物件標記) (javascript 物件標記語言) 是一種輕量級

文章豁然開朗成為架構師必須了解的一些疑問

有一點 同事 繼續 模式 常見 瓶頸 功能實現 很多 獨立 前言:我先介紹一下我的新同事,公司好多同事都這麽叫他James,有10年開發經驗的架構師,之前在人人網待過,之後我們也聊了很多。 在聊天過程中,我們也聊到了他為什麽離開人人網,也聊到了他在成為架構師的道路上的辛酸歷

#文章瞭解四種執行緒池學習Java不在困惑

在Java開發中,有時遇到多執行緒的開發時,直接使用Thread操作,對程式的效能和維護上都是一個問題,使用Java提供的執行緒池來操作可以很好的解決問題,於是找了下API看到Java提供四種執行緒池使用,Java通過Executors提供四種執行緒池,分別為: 1、newCachedThrea

文章豁然開朗成為架構師必須瞭解的一些疑問

前言: 我先介紹一下我的新同事,公司好多同事都這麼叫他James,有10年開發經驗的架構師,之前在人人網待過,之後我們也聊了很多。 在聊天過程中,我們也聊到了他為什麼離開人人網,也聊到了他在成為架構師的道路上的辛酸歷程,聊過後,才發現,離開人人網的原因和他的架構師之路和我

文章讀懂什麽是餐飲小程序

用戶 事情 right 連接 不用 距離 掃描二維碼 left 企業 小程序火了,餐飲+小程序也火了! 作為連接線下消費場景和線上營銷的新工具,小程序出現後,迅速贏得了餐飲商家的青睞。與其說,小程序對餐飲行業“情有獨鐘”;不如說,兩者是“情投意合”。 20天

文章明白python的裝飾器

pri 9.png 不同 概念 ota 一起 數字 上下文 讀取 在看閉包問題之前先來看看關於python中作用域的問題 變量作用域 對於上述代碼中出現錯誤,肯定沒什麽疑問了,畢竟b並沒有定義和賦值,當我們把代碼更改如下後: 再看一個例子: 首先這個錯誤已經非常明顯

文章了解DNS

遞歸查詢 叠代查詢 反向解析 DNS報文格式 目錄什麽是DNSDNS的特點DNS的工作原理反向解析DNS的報文格式一、什麽是DNS DNS--Domain Name System,域名系統。 互聯網中計算機之間進行通訊,數據怎麽走,走向哪裏,這些都需要根據IP地址來

爬蟲是什麽爬蟲能幹啥爬蟲怎麽爬文章教會所有

school 語句 詳細 優勢 body 谷歌 class ddd 教程 這篇文章的定位是,給有一些python基礎,但是對爬蟲一無所知的人寫的。文中只會涉及到爬蟲最核心的部分,完全避開莫名其妙的坑或概念,讓讀者覺得爬蟲是一件非常簡單的事情,而事實上爬蟲確實是一件非常簡單的

文章知道什麽是數據挖掘

大數據 數據挖掘 數據庫 大數據如果想要產生價值,對它的處理過程無疑是非常重要的,其中大數據分析和大數據挖掘就是最重要的兩部分。在前幾期的科普中,小編已經為大家介紹了大數據分析的相關情況,本期小編就為大家講解大數據挖掘技術,讓大家輕輕松松弄懂什麽是大數據挖掘技術。什麽是大數據挖掘?數據挖掘(Dat

文章快速入門 學懂Shell腳本

運行 turn origin 判斷語句 load for循環 網絡操作 場景 個數字 Shell腳本,就是利用Shell的命令解釋的功能,對一個純文本的文件進行解析,然後執行這些功能,也可以說Shell腳本就是一系列命令的集合。 Shell可以直接使用在win/Uni

前端開發實用比較文章告訴到底是用Vue還是用Angular4、5?

從Angular2時代開始,前端開發就逐漸開始用用Angular了,當時全國都沒什麼人敢碰Angular2,多數開發者就靠著啃它原始碼中的註釋,熟悉了Angular2的用法,並在實用中,還給Angular2團隊提交bug。 但是現在,Vue的出現,讓很多還沒接觸Angular多久的開發者

文章瞭解GC垃圾回收器

簡單瞭解GC垃圾回收器 瞭解GC之前我們首先要了解GC是要做什麼的?顧名思義回收垃圾,什麼是垃圾呢? GC回收的垃圾主要指的是回收堆記憶體中的垃圾物件。 從根物件出發,所有被引用的物件,都是存活物件 其他物件,都是垃圾物件。  根物件:    棧中的引用變數,所引用的物

文章了解GC垃圾回收器

存滿 需要 進行 並行 mil 之間 consola 微軟雅黑 並行執行 簡單了解GC垃圾回收器 了解GC之前我們首先要了解GC是要做什麽的?顧名思義回收垃圾,什麽是垃圾呢? GC回收的垃圾主要指的是回收堆內存中的垃圾對象。 從根對象出發,所有被引用的對象,都是存活對象 其

文章真正讀懂HashMap

前言------ 在使用HashMap的過程中,是否對key值不能重複有過疑問? 是否對改原因百思不得其解? 是否只會使用常用方法?  是否很想理解hash演算法為基礎的HashMap?  如果有, 那麼恭喜你哈, 找對文章了! 歡迎轉載,轉載請註明來源  

#Java乾貨分享:文章深入瞭解Java中的包和介面

很多新手程式設計師對於Java中兩個具創新性的特徵————包與介面不是非常清楚,所以我特意發了這篇文章來闡述什麼是包,什麼是介面。 包(package)是多個類的容器,它們用於保持類的名稱空間相互隔離。 如果有想學習java的程式設計師,可來我們的java學習扣qun:79979,2590免

文章瞭解大資料採集技術

大資料開啟了一個大規模生產、分享和應用資料的時代,它給技術和商業帶來了巨大的變化。麥肯錫研究表明,在醫療、零售和製造業領域,大資料每年可以提高勞動生產率0.5-1個百分點。大資料在核心領域的滲透速度有目共睹,然而調查顯示,未被使用的資訊比例高達99.4%,很大程度都是由於高價值的資訊無法獲取採集。因

文章不再擔心浮動

浮動的效果 文件流 文件流是文件中可顯示物件在排列時所佔用的位置。 將窗體自上而下分成一行行, 並在每行中按從左至右的順序排放元素,即為文件流.(自己的理解是從頭到尾按照文件的順序,該在什麼位置就在什麼位置,也可以按照上面的意思理解,自上而下,自左到右的順序) 浮動的特點