通过简单的例子学习 Dagger2

我已经阅读并观看了很多不同的 Dagger2 教程,但大多数都太长或难以理解所以我决定为 Dagger2 编写一个新的简单和简短的教程,我希望你喜欢它。

为什么我们需要它?

  • 简化对共享实例的访问:它提供了一种获取对共享实例的引用的简单方法,例如,一旦我们在 Dagger 中声明我们的单例实例(如 SharedPrefrences),我们就可以使用简单的 @Inject 注释声明字段。
  • 更简单的单元和集成测试:我们可以轻松交换出网络响应的模块并模拟这种行为。

以一个简单的例子开始

我的 GitHub 帐户上提供了完整的示例源代码。

添加 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);
  }
}

就是这样,我希望你喜欢。