Dagger2入門使用

渣渣008發表於2017-12-13

dagger 1.x 以前只是聽說過,沒使用過,也不打算再研究啦。 最近在看有關元件化的文章,講道理,元件化如果約定好了,唯一需要解決的可能就是元件之間的通訊了。 按照我的理解,元件化大概是這樣:基礎庫+元件+元件+...+主module,基礎庫可以按照功能分成style庫,util庫,自定義控制元件庫,這些庫可以釋出到內部maven裡面,各個元件可以引用其中的某個庫,或者引用所有的,或者不引用。 各個元件之間的通訊分為兩個部分,一個是元件之間的跳轉,一個是元件的資料交換,對於元件之間的跳轉可以使用Router之類的庫,元件之間的資料交換可能就會比較麻煩了。 元件間的資料交換,我的初步想法是通過介面,需要交換的資料寫一些介面也做成一個庫,其他的元件可以引用這個庫,做處理然後返回對應的資料。 有大神提到他們公司的元件之間的通訊是使用的一個二次開發的dagger2庫,所以這次主要來寫篇daager2的入門使用文章。

dagger2庫的地址:github.com/google/dagg…

依賴配置

dependencies {
    // 你的其他依賴庫
    compile 'com.google.dagger:dagger:2.9'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.9'
}
複製程式碼

dagger2採用的是編譯時註解時註解,以前可能用的是apt,Gradle從2.2版本開始支援annotationProcessor功能來代替Android-apt。android-apt外掛作者近期已經發表宣告表示後續不會再繼續維護該外掛。 關於如何從apt切換到annotationProcessor可以參考下圖。

Dagger2入門使用
圖取自 擴充篇:註解處理器最佳實踐

概念

好吧,其實看了官方Demo,和很多文章之後,感覺dagger2就是用來生成物件的,當然它用編譯時註解做了一些自動化的事情(媽蛋,不要看一些文章說什麼依賴注入,聽著好像挺厲害的樣子,很多時候不是自己不夠聰明,而是別人說的不夠明白)。以前學習過spring,瞭解過一些這方面的知識。

daager2的好處呢,一是因為生成物件在一個獨立的地方,所以修改的時候方便些,測試會簡單些,還有就是如果一個物件需要很多其他物件的引用,使用dagger2生成會方便很多的。

  • @Inject 既然dagger2是用來生成物件的,我們肯定需要知道哪些物件是需要生成的啦,這個註解其中一個作用就是用來告訴dagger2,這個物件需要被生成。 還有一個作用是給構造方法新增此註解,標記建構函式,dagger2通過@Inject註解可以在需要這個物件的時候,找到這個建構函式並生成物件,給被@Inject標記了的變數提供物件。

  • @Module @Module用於標註提供物件的類。上面已經提供了@Inject,這裡還提供@Module,其實呢,當需要生成的物件是第三方的jar包,或者物件有構造引數的時候,@Inject並不會特別的方便。

  • @Provides 用於標註@Module標註的類中,提供物件的方法。

  • @Component 用於標註介面,是@Inject和@Module之間的橋樑。被Component標註的介面在編譯時會生成該介面的實現類(如果@Component標註的介面為CarComponent,則編譯期生成的實現類為DaggerCarComponent),我們通過呼叫這個實現類的方法完成物件的賦值。

  • @Qualifier dagger裡面在同一個Module裡面提供兩個相同的物件是不允許的,這樣dagger無法分辨,這個時候就需要使用Qualifier去自定義不同的註解限定需要提供的是哪種型別的物件。

  • @Scope 用於自定義註解,可以通過@Scope自定義的註解來限定註解作用域,實現區域性的單例。

  • @Singleton 一個通過Scope定義的註解,一般通過它來實現全域性單例。但實際上它並不能提前全域性單例,是否能提供全域性單例還要取決於對應的Component是否為一個全域性物件。

基本使用

比如,我們使用dagger生成使用者User物件。

1.建立User類

public class User {
    private String name;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}
複製程式碼

2.建立使用者生成類,即對應的Module

@Module
public class UserModule {

    public UserModule() {
    }

    @Provides
    User provideUser() {
        return new User();
    }

}
複製程式碼

3.建立對應的Component連線Module和Inject

這裡Inject還沒用上,被@Inject標註的物件就表示是需要UserModule提供的。

@Component(modules = UserModule.class)
public interface UserComponent {
    void inject(MainActivity activity);
}
複製程式碼

4.生成程式碼,使用

點選As上面的make project按鈕,對應的程式碼就會在專案的對應的module的/build/generated/source/apt裡面。 然後在MainActivity裡面使用生成的對應UserComponent介面的DaggerUserComponent物件即可,dagger預設生成的Component物件即在介面前面加上Dagger。

        UserComponent userComponent = DaggerUserComponent.create();
        userComponent.inject(this);
複製程式碼

上面只是最簡單的使用,後面的文章會比較詳細的介紹每個關鍵字的用法,以及結合更多的例項。