dagger-2开始使用dagger-2


备注

本节概述了dagger-2是什么,以及开发人员为什么要使用它。

它还应该提到匕首-2中的任何大型主题,并链接到相关主题。由于dagger-2的文档是新的,您可能需要创建这些相关主题的初始版本。

版本

发布日期
2.5 2016年6月14日
2.6 2016年7月27日
2.7 2016年9月13日
2.8 2016年11月22日
2.9 2017年2月3日
2.10 2017年3月15日

Android示例

使用Dagger编写Android应用程序的一个主要困难是,许多Android框架类都由操作系统本身实例化,如ActivityFragment ,但如果Dagger可以创建所有注入的对象,则效果最佳。相反,您必须在生命周期方法中执行成员注入。从版本2.10开始,dagger允许使用dagger.android ,这简化了使用dagger和android组件。

注入Activity对象

  1. 在应用程序组件中安装AndroidInjectionModule ,以确保这些基本类型所需的所有绑定都可用。

    @Component(modules = {AndroidInjectionModule.class})
    public interface AppComponent {}
     
  2. 通过编写一个开始@Subcomponent 实现[AndroidInjector] [AndroidInjector],用@Subcomponent.Builder 扩展[AndroidInjector.Builder] [AndroidInjector.Builder]:

    @Subcomponent
    public interface MainActivityComponent extends AndroidInjector<MainActivity> {
        @Subcomponent.Builder
        abstract class Builder extends AndroidInjector.Builder<MainActivity> {}
    }
     
  3. 定义子组件后,通过定义绑定子组件构建器的模块并将其添加到注入Application 的组件,将其添加到组件层次结构中:

    @Module(subcomponents = MainActivityComponent.class)
    public abstract class MainActivityModule {
    
        @Binds @IntoMap @ActivityKey(MainActivity.class)
        abstract AndroidInjector.Factory<? extends Activity>
        bindMainActivityInjectorFactory(MainActivityComponent.Builder builder);
    }
     
  4. 接下来,使您的Application 实现HasDispatchingActivityInjector@Inject a DispatchingAndroidInjector<Activity> 以从activityInjector()方法返回:

    public class MyApp extends Application implements HasDispatchingActivityInjector     {
    
        @Inject
        DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
    
        @Override
        public void onCreate() {
           super.onCreate();
           DaggerAppComponent.create().inject(this);
        }
    
        @Override
        public DispatchingAndroidInjector<Activity> activityInjector() {
            return dispatchingActivityInjector;
        }
    }
     
  5. 最后,在Activity.onCreate() 方法中,在调用AndroidInjection.inject(this) 之前调用super.onCreate();

    public class MainActivity extends Activity {
        public void onCreate(Bundle savedInstanceState) {
            AndroidInjection.inject(this);
            super.onCreate(savedInstanceState);
        }
    }
     

此示例基于官方匕首文档 。工作样本可以在github上找到

基本例子

定义一个模块(依赖关系模型及其图形):

@Module
public class CoffeeModule{

    @Provides
    public CoffeeMaker provideCoffeeMaker(){
         return new CoffeeMaker();
    }

    @Provides
    public Coffee provideCoffee(CoffeeMaker coffeeMaker){
        return new Coffee(coffeeMaker);
    }

}
 

定义组件:

@Component(
    modules={
        CoffeeModule.class
    }
)
interface CoffeeComponent {

        DeveloperActivity inject(DeveloperActivity developerActivity);
}
 

注入依赖项:

class DeveloperActivity extends ...{

    @Inject
    Coffee myCoffee;

    @Override
    protected void onCreate(Bundle savedInstanceState) {           
        super.onCreate(savedInstanceState);

        DaggerCoffeeComponent.builder()
                .coffeeModule(new CoffeeModule())
                .build()
                .inject();
       
    }

}
 

说明和设置

什么是Dagger 2?

该网站将自己描述为:

Dagger是一个完全静态的编译时依赖注入框架

该库使得对依赖图进行建模以及重用对象变得容易。由于反射仅在编译时用作注释处理的一部分,因此Dagger 2提高了依赖注入的速度。

建立

1-添加对注释处理的支持:

Android的

顶级build.gradle 脚本:

 repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }
 

模块级build.gradle 脚本:

apply plugin: 'com.neenbedankt.android-apt'
 

Java的

plugins {
  id "net.ltgt.apt" version "0.5"
}    
 

2-添加匕首2依赖项

 dependencies {
      compile 'com.google.dagger:dagger:2.x'
      apt 'com.google.dagger:dagger-compiler:2.x'
    }
 

通过简单的例子学习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);
  }
}
 

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