通过简单的例子学习 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);
}
}
就是这样,我希望你喜欢。