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可以參考下圖。
圖取自 擴充篇:註解處理器最佳實踐概念
好吧,其實看了官方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);
複製程式碼