依賴注入框架Dagger2—1.入門
1.依賴注入
1.1.什麼是依賴?
如果在 Class A 中,有 Class B 的例項,則稱 Class A 對 Class B 有一個依賴。 例如下面類 A 中用到一個 B 物件,我們就說類 A 對類 B 有一個依賴。 同時,這也是一個典型的"依賴非注入"案例。
public class A {
...
B b;
...
public A() {
b = new B();
}
}
1.2.什麼是依賴注入?
依賴注入就是給一個物件傳入一個例項變數。 比如:
public class A {
...
B b;
. ..
public A(B b) {
this.b = b;
}
}
這是一個通過建構函式傳參進行注入,在A類裡邊不再有new B()的操作,所以A不再依賴B,還有通過方法進行注入,比如常見的setXXX(B b)。 這種就是最簡單的依賴注入。 更詳細請參考:http://blog.51cto.com/cnn237111/928690
1.3.為什麼要用依賴注入?
專案中,經常需要在一個物件裡去建立另一個物件的例項,這種行為是產生耦合的常見形式,對於一個大型專案來說,過多的相互依賴會導致程式碼難以維護,如何難以維護?比如A的構造內new了一個B,B的構造變了,那麼我們就要去A的構造內修改構建B的程式碼,這樣,地方一多,工作量就會很大。 我們可以通過上面的方式進行依賴注入,但是難免顯得簡陋,那麼在這裡可以引出本文要學習的主題—Dagger。
2.Dagger
2.1.什麼是Dagger?
在瞭解了依賴注入之後,再來看Dagger,它是一個依賴注入框架,它在Github主頁上的自我介紹是:“A fast dependency injector for Android and Java“(一個提供給Android和Java使用的快速依賴注射器。) 它最開始由Square這個公司出品,後來被google吸收由谷歌來接手維護。
2.2.使用Dagger2的最大好處是什麼?它有什麼作用?
模組間解耦! 就拿當前Android非常流行的開發模式MVP來說,使用Dagger2可以將MVP中的V 層與P層進一步解耦,這樣便可以提高程式碼的健壯性和可維護性。
2.3.如何理解Dagger2的運作原理?
為了便於理解,其實可以把component想象成針管,module是注射瓶,裡面的依賴物件是注入的藥水,build方法是插進患者(Container),inject方法的呼叫是推動活塞。
圖片主要分為三部分,左邊的是依賴提供者,比如用Module標註的類或者用Injection標註的建構函式,右邊的是依賴的需求方,例如我們用inject標註的變數,而Component則是連線兩者的橋樑,Component從依賴提供者提供依賴,並把這些依賴注入相關的類中,Dagge正如其名,就像把匕首讓依賴能夠非常犀利的注入到需要它的地方。
2.4.Dagger2相較於Dagger1的優勢是什麼?
**更好的效能:**相較於Dagger1,它使用的預編譯期間生成程式碼來完成依賴注入,而不是用的反射。大家知道反射對手機應用開發影響是比較大的,因為反射是在程式執行時載入類來進行處理所以會比較耗時,而手機硬體資源有限,所以相對來說會對效能產生一定的影響。
**容易跟蹤除錯:**因為dagger2是使用生成程式碼來實現完整依賴注入,所以完全可以在相關程式碼處下斷點進行執行除錯。
3.Dagger2—Hello World
瞭解了一些概念和原理之後,接下來上手練練。
3.0.庫新增
引入:
implementation "com.google.dagger:dagger:2.9"
annotationProcessor "com.google.dagger:dagger-compiler:2.9"
3.1.Hello Dagger
未使用Dagger的時候:
package android.zj.com.zjmine;
public class A {
public A() {}
}
**********************
public class MainActivity {
...
A a;
...
onCrete(){
a = new A();
a.toString();
}
}
若用了Dagger2:多了一個Component,它是橋樑的意思,誰的橋樑,moudle和container的橋樑,它直接就Moudle-A注入到Container-(inject)-MainActivity裡邊去了,解耦了依賴,沒有去new Object()。這就是一個最簡單的Dagger2使用。涉及到的註解就倆 @inject, @Component,當然還有其他屬性,不過篇幅限制留到下一篇。
package android.zj.com.zjmine;
public class A {
@inject
public A() {}
}
**********************
public class MainActivity {
...
@inject A a;
...
onCrete(){
//注入,注意這個類DaggerXXXComponent需要提前make一下專案
DaggerMainActivityComponent.builder().build().inject(this);
a.toString();
}
}
/**
*Component必須是一個介面類或者抽象
*/
@Component
interface MainActivityComponent {
void inject(MainActivity mainActivity);
}
3.總結
本文主要入門了Dagger的一些基礎知識,比如什麼是依賴?
依賴就是在一個類A中去new另一個類B的物件,這就叫A依賴了B。
什麼是依賴注入?
常規的構造方法對變數物件賦值,set方法對變數物件賦值,這就是最簡單的依賴注入。
為什麼要用依賴注入?
為了減少程式碼的維護成本,降低專案內程式碼的耦合性。
為什麼要使用Dagger2?
對傳統的依賴注入進一步的解耦,通過apt在編譯期間在路徑\build\generated\source\apt\develop\debug\packagename
下動態生成MembersInjector,Factory,Component
以達到在需求改變,構造方式,或者其他可變因素改變的情形下,我們不需要改動我們業務元件內的例項化程式碼(比如Controller,ViewMoudle,Presenter)
的這樣一種效果,當然Dagger2不僅僅是優化了物件的構造這一項內容,還有其他的高階特性,這受限於研究的深度需要慢慢積累,本文目的是入門。