通俗易懂的dagger2-入門篇

1111111_發表於2017-09-22

1 什麼是Dagger

一個Android和java快速依賴注射器。

1.1 關於Dagger

Dagger 2是依賴注入的編譯時進化方法。 採用Dagger 1.x開始的方法達成最終結論,Dagger 2.x消除了所有的反射,並通過刪除傳統的ObjectGraph / Injector來改善程式碼清晰度,有利於使用者指定的@Component介面。

這個github專案代表了Dagger 2開發流。 較早的專案頁面(Square,Inc的儲存庫)代表較早的1.0開發流。 這兩個版本都受益於Square,Google和其他貢獻者的強烈參與。

Dagger 2目前正在積極發展,主要是內部在 Google,定期推動開源社群。 快照版本將自動部署到sonatype的中央maven儲存庫,每個乾淨的版本與版本HEAD-SNAPSHOT。

官網原文:
Dagger 2 is a compile-time evolution approach to dependency injection. Taking the approach started in Dagger 1.x to its ultimate conclusion, Dagger 2.x eliminates all reflection, and improves code clarity by removing the traditional ObjectGraph/Injector in favor of user-specified @Component interfaces.

This github project represents the Dagger 2 development stream. The earlier project page (Square, Inc's repository) represents the earlier 1.0 development stream. Both versions have benefitted from strong involvement from Square, Google, and other contributors.

Dagger is currently in active development, primarily internally at Google, with regular pushes to the open-source community. Snapshot releases are auto-deployed to sonatype's central maven repository on every clean build with the version HEAD-SNAPSHOT.

1.2 為什麼Dagger 2是不同的

依賴注入框架已經存在多年,具有用於配置和注入的各種API。那麼,為什麼要重新發明輪?Dagger 2是第一個用生成的程式碼實現完整堆​​棧的。指導原則是生成模仿使用者可能手寫的程式碼的程式碼,以確保依賴注入是可以簡單,可追溯和執行的。

官網原文:
Dependency injection frameworks have existed for years with a whole variety of APIs for configuring and injecting. So, why reinvent the wheel? Dagger 2 is the first to implement the full stack with generated code. The guiding principle is to generate code that mimics the code that a user might have hand-written to ensure that dependency injection is as simple.


2 使用Dagger 2

因為現在android studio 3.0在測試,基本上都是使用as 2.3.3就無需再加入外掛了,直接在appbuild.gradledependencies 中加入依賴就可以開始使用了。

2.1 新增依賴

compile 'com.google.dagger:dagger:2.x'
annotationProcessor 'com.google.dagger:dagger-compiler:2.x'

x是版本號,目前最新的是2.11,檢視最新版

2.2 常用註解

2.2.1 @Inject

用於告訴Dagger2,我們需要這個類的例項物件。主要用於標記哪個類是需要注入的,可標註在物件或方法上,不能標記private修飾的。

2.2.2 @Module

用於對外提供物件,一般可在@Module標註的類中新增自定義方法,方法標註@Provides,方法體中可用來做一些例項化操作等。

2.2.3 @Provides

配合@Module一起使用,@Provides用於標記方法,表示可以通過這個方法獲取一個物件,一般用於自定義類中。

2.2.4 @Component

主要用於關聯@Module標註的類和Activity及Fragment的子類。

2.2.5 @Named 和 @Qualifier

用於區別不同物件的例項,必須要成對出現。@Named是以自己定義的字串去識別,@Qualifier是以註解類(@interface)去識別。

2.2.6 @Singleton

dagger 2中的單例模式,@Module類中使用了,@Component中也要使用。

2.2.7 @scope

Scopes可是非常的有用,Dagger2可以通過自定義註解限定註解作用域。這個註解我也不太熟悉,具體可以參考網路或官網。

2.3 舉個栗子

先拿一個簡單的網路請求依賴注入。
整個包的結構最重要的就是 di 包下兩個,network 包下是封裝的一個簡單的 retrofit 2.0 網路請求

structure.png
structure.png

為了快速的看懂module和component中的程式碼,我們先看看network包下的程式碼,上程式碼

ApiService.class
ApiService.class

RetrofitClient.clss
RetrofitClient.clss

貼心程式碼

------ApiService.class------

@GET("data/{type}/{count}/{page}")
Observable<ResponseBody> getGank(@Path("type") String type,
                                 @Path("count") int count,
                                 @Path("page") int page);
}

------RetrofitClient.class------
/**
 * 請求超時時間
 */
private static final long DEFAULT_TIMEOUT = 10 * 1000;

/**
 * 伺服器地址url
 */
private static final String BASE_URL = "http://gank.io/api/";

private static ApiService sApiService;

public static ApiService getDefault() {
    if (null == sApiService) {
        synchronized (RetrofitClient.class) {
            if (null == sApiService) {
                OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder()
                        //設定超時時間
                        .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
                        .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
                        .readTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
                sApiService = new Retrofit.Builder()
                        .client(httpClientBuilder.build())
                        .addConverterFactory(GsonConverterFactory.create())
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .baseUrl(BASE_URL)
                        .build().create(ApiService.class);
            }
        }
    }
    return sApiService;
}複製程式碼

好了,一個超普通的 retrofit 請求封裝。下面再看看 NetworkModule.class

NetworkModule.class
NetworkModule.class

想必看也看得懂吧,一個類被標記 @Module 提供一個@Provides標記的方法,providesApiService()用於返回一個retrofit例項。程式碼就不貼出來了,多敲敲就會了 (=^ ^=)

再來看看NetworkComponent.class,他相當於是一個聯結器,連線activity子類module

NetworkComponent.class
NetworkComponent.class

注意:inject()中引數不能寫Activity,否則會報空指標。

馬上就快完成了,在 MainActivity.class 中注入

MainActivity.clss
MainActivity.clss

物件 ApiService 通過 @Inject 注入,DaggerNetworkComponent 是由系統生成的(as選單欄BuildRebuild Project),如果找不到 DaggerNetworkComponent 就是你寫錯了,具體看log資訊。


結尾:
在@Component中有一個dependencies,可以理解為依賴。過幾天我會寫一個dagger2在mvp中應用的部落格,會把dagger的基礎使用都寫上,謝謝大家 (=^ ^=)

相關文章