通過簡單的例子學習 Dagger2
我已經閱讀並觀看了很多不同的 Dagger2 教程,但大多數都太長或難以理解所以我決定為 Dagger2 編寫一個新的簡單和簡短的教程,我希望你喜歡它。
為什麼我們需要它?
- 簡化對共享例項的訪問:它提供了一種獲取對共享例項的引用的簡單方法,例如,一旦我們在 Dagger 中宣告我們的單例例項(如
SharedPrefrences
),我們就可以使用簡單的@Inject
註釋宣告欄位。 - 更簡單的單元和整合測試:我們可以輕鬆交換出網路響應的模組並模擬這種行為。
以一個簡單的例子開始
新增 Dagger2 依賴項
首先,我們需要新增 Dagger2 依賴項,將下面的程式碼放到模組級 build.gradle 檔案中。
compile "com.google.dagger:dagger:$dagger_version"
compile "com.google.dagger:dagger-android:$dagger_version"
compile "com.google.dagger:dagger-android-support:$dagger_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
如果你收到錯誤:錯誤:與專案’:app’中的依賴項’com.google.code.findbugs:jsr305’發生衝突,則應將以下內容新增到主 app / build.gradle 檔案中。
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
}
兩個簡單的類
我們有兩個類(Vehicle 和 Motor),Vehicle 類需要執行 Motor 類,MainActivity 需要 Vehicle 類。我們將使用 Dagger2 來提供這些例項。
class Vehicle {
private Motor motor;
@Inject
Vehicle(Motor motor) {
this.motor = motor;
}
void increaseSpeed(int value) {
motor.accelerate(value);
}
void decreaseSpeed(int value) {
motor.decelerate(value);
}
void stop() {
motor.brake();
}
int getSpeed() {
return motor.getRpm();
}
}
電機類:
class Motor {
private int rpm;
Motor() {
this.rpm = 0;
}
int getRpm() {
return rpm;
}
void accelerate(int value) {
rpm += value;
}
void decelerate(int value) {
rpm -= value;
}
void brake() {
rpm = 0;
}
}
模組類
模組類負責提供可以注入的物件。在這個例子中,我們要將 Motor 類注入 Vehicle 類並將 Vehicle 類注入 MainActivity,因此我們應該建立 MyModule 來提供這些例項。
@Module
class MyModule {
@Provides
@Singleton
Motor provideMotor() {
return new Motor();
}
@Provides
@Singleton
Vehicle provideVehicle() {
return new Vehicle(new Motor());
}
}
@Provide 註釋: 此方法返回的物件可用於依賴注入。
@Component 介面
Dagger2 需要元件介面來知道它應該如何從我們的類建立例項。
@Singleton
@Component(modules = {MyModule.class})
interface MyComponent {
Vehicle provideVehicle();
void inject(MainActivity main);
}
@Component 介面: 物件提供者與表示依賴關係的物件之間的連線。
在建構函式中注入依賴項
通過新增 @Inject 註釋,dagger2 可以自動從該物件建立一個例項,就像我們在 Vehicle 類中的示例 Motor 物件一樣。
在 MainClass 中注入依賴項
Dagger2 可以自動在建構函式中注入依賴項,但 Android 元件(活動,片段等)由 Android 框架例項化,這使得很難對它們使用依賴注入,因此我們應該像下面的程式碼一樣手動注入它們:
public class MainActivity extends AppCompatActivity {
@Inject
Vehicle vehicle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyComponent component = DaggerMyComponent.builder().build();
component.inject(this);
}
}
就是這樣,我希望你喜歡。