Dagger2入坑之旅 一

关于dagger2在这里

关于依赖注入的基础知识在这里

导入

根目录build.gradle文件:

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

项目build.gradle文件:

apply plugin: 'android-apt'


apt 'com.google.dagger:dagger-compiler:2.2'
compile 'com.google.dagger:dagger:2.2'
//java注解
provided 'org.glassfish:javax.annotation:10.0-b28'

\\

Dagger2的每一个概念:

  • @Inject: 通常在需要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段需要依赖注入。这样,Dagger就会构造一个这个类的实例并满足他们的依赖。

  • @Module: Modules类里面的方法专门提供依赖,所以我们定义一个类,用@Module注解,这样Dagger在构造类的实例的时候,就知道从哪里去找到需要的 依赖。modules的一个重要特征是它们设计为分区并组合在一起(比如说,在我们的app中可以有多个组成在一起的modules)。

  • @Provide: 在modules中,我们定义的方法是用这个注解,以此来告诉Dagger我们想要构造对象并提供这些依赖。

  • @Component: Components从根本上来说就是一个注入器,也可以说是@Inject和@Module的桥梁,它的主要作用就是连接这两个部分。 Components可以提供所有定义了的类型的实例,比如:我们必须用@Component注解一个接口然后列出所有的

  • @Modules组成该组件,如 果缺失了任何一块都会在编译的时候报错。所有的组件都可以通过它的modules知道依赖的范围。

  • @Scope: Scopes可是非常的有用,Dagger2可以通过自定义注解限定注解作用域。后面会演示一个例子,这是一个非常强大的特点,因为就如前面说的一样,没 必要让每个对象都去了解如何管理他们的实例。在scope的例子中,我们用自定义的

  • @PerActivity注解一个类,所以这个对象存活时间就和 activity的一样。简单来说就是我们可以定义所有范围的粒度(@PerFragment, @PerUser, 等等)。

  • Qualifier: 当类的类型不足以鉴别一个依赖的时候,我们就可以使用这个注解标示。例如:在Android中,我们会需要不同类型的context,所以我们就可以定义 qualifier注解’@ForApplication’和“@ForActivity”,这样当注入一个context的时候,我们就可以告诉 Dagger我们想要哪种类型的context。

使用

看了基础介绍后,然后就是怎么用了
就用一个非常简单的例子来说明怎么使用,现在有两个类:

public class Motor {
    private int rpm;

    public Motor(){
        this.rpm = 0;
    }

    public int getRpm(){
        return rpm;
    }

    public void accelerate(int value){
        rpm = rpm + value;
    }

    public void brake(){
        rpm = 0;
    }
}
public class Vehicle {
    private Motor motor;


    public Vehicle(Motor motor){
        this.motor = motor;
    }

    public void increaseSpeed(int value){
        motor.accelerate(value);
    }

    public void stop(){
        motor.brake();
    }

    public int getSpeed(){
        return motor.getRpm();
    }
}

然后我们的需求是调用Vehicle里的increaseSpeed();设置速度然后调用getSpeed()显示;
一般通常的做法是:

Motor motor = new Motor();
Vehicle vehiclev = new Vehicle(motor);
vehicle.increaseSpeed(22);
Log.d(TAG,String.valueOf(vehicle.getSpeed()));

但是用dagger2的做法就不一样了, Vehicle 和 Motor 。 Motor 是独立类, Vehicle 是依赖类,所以首先先改变一下Vehicle类的构造函数,如下:

public class Vehicle {
    private Motor motor;

    @Inject
    public Vehicle(Motor motor){
        this.motor = motor;
    }

    public void increaseSpeed(int value){
        motor.accelerate(value);
    }

    public void stop(){
        motor.brake();
    }

    public int getSpeed(){
        return motor.getRpm();
    }
}

可以发现在构造函数上加了 @Inject;

然后我们需要创建一个VehicleModule:

@Module
public class VehicleModule {

    @Provides
    @Singleton
    Motor provideMotor(){
        return new Motor();
    }


}

@Singleton 表示注解指明对象只能有一个实例
但这并没有结束,最后我们需要创建一个VehicleComponent来链接他们

@Singleton
@Component(modules = {VehicleModule.class})
public interface VehicleComponent {
    void inject(MainActivity activity);
}

使用带 @Component 注解的接口连接依赖的提供者;这样就结束了,下面就是在MainActivity调用依赖了:

public class MainActivity extends AppCompatActivity {


    private TextView text;
    @Inject
    Vehicle vehicle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView) findViewById(R.id.text);
        DaggerVehicleComponent.builder()
                .vehicleModule(new VehicleModule())
                .build()
                .inject(this);
        vehicle.increaseSpeed(22);
        text.setText(String.valueOf(vehicle.getSpeed()));

    }
}

如上代码,先声明一个Vehicle对象并在对象上加上@Inject然后点击AndroidStudio的Build/Make Project;这样AS会自动帮你生成对应的代码去关联依赖(生成的代码位置在:app/build/generated/source/apt/debug);最后

DaggerVehicleComponent.builder()
                .vehicleModule(new VehicleModule(new Motor()))
                .build()
                .inject(this);

初始化它后就可以使用了;看完后是不是很晕它为什么要这么写;为什么就可以成功了?别急后面为你解惑

你可能感兴趣的:(android)