Android Dagger (二) Provides 、Lazy、Qualifier、Scope 等

版权声明:本文为博主原创文章,转载请说明出处。 https://blog.csdn.net/qq_30889373/article/details/81605113

@Provides

上文其实已经讲到,这里重复一下概念

@Provides 可以认为是 @ibject的补充,比如我们使用 OkHttp库 其他第三库时,我们并无法直接注入


每定义一个方法,都将生成 独立的 .java文件
比如下面代码:

- 生成文件列表
– DemoModule_ProvidePerson1Factory.java
– DemoModule_ProvidePerson2Factory.java
– DemoModule_ProvidePerson3Factory.java

@Module
public class DemoModule {

    @Provides
    Person providePerson1(){
        return new Person();
    }

    @Provides
    Person providePerson2(){
        return new Person();
    }

    @Provides
    Person providePerson3(){
        return new Person();
    }
}

Lazy

延迟注入,其实与 kotlin的 lazy 相同概念

只有在调用 Lazy 的 get() 方法时才会初始化依赖实例注入依赖

public class Person {
    @Inject
    Lazy<Car> lazyCar;

    public void goWork() {
        ...
        lazyCar.get().go(); // lazyCar.get() 返回 Car 实例
        ...
    }
}

Qualifier

上面的 DemoModule 提供了三个方法 但是都返回了 Person,
那 dagger 怎么知道我们要使用哪个返回的Person呢? 在编译时就会报错

网上说法,叫依赖迷失, 那如何解决,主人公 Qualifier就派上用场了

module

@Module
public class DemoModule {
    @Provides
    @Named("person1")
    Person providePerson1(){
        return new Person();
    }
    .. 以此类推
}

component

@Component(modules = DemoModule.class)
public interface DemoCompoent {
    void inject(DemoActivity activity);
}

activity

public class DemoActivity extends AppCompatActivity {
    @Inject
    @Named("person1")
    Person person;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);

        DaggerDemoCompoent.create().inject(this);
        // 搞定
 ((TextView)findViewById(R.id.tv_content)).setText(String.valueOf(person.hashCode()));
    }
}

Scope <作用域>

Scope 是用来确定注入的实例的生命周期的,如果没有使用 Scope 注解,Component 每次调用 Module 中的 provide 方法或 Inject 构造函数生成的工厂时都会创建一个新的实例

这里写图片描述
我们先来设想下这样的场景
这里写图片描述
显然如果我们不做任何处理 @Inject注入,每个人都会有一辆车。
那么如何避免? Scope 来了~

定义对象

public class Wang {
    Car car;

    public Wang(Car car) {
        this.car = car;
        System.out.println("我是王 我的车子对象是 -> " + car.hashCode());
    }
}

public class Zhang {
    Car car;

    public Zhang(Car car) {
        this.car = car;
        System.out.println("我是张 我的车子对象是 -> " + car.hashCode());
    }

}

scope

固定格式,主要是名字 跟 使用位置区分

@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface CarScope {}

module

@Module
public class CarModule {

    @Provides
    @CarScope  // 自定义作用域,可以尝试注释掉,然后最后输出就变为了三个car
    Car provideCar(){
        return new Car();
    }
}

@Module
public class DemoModule {

    @Provides
    Zhang provideZhang(Car car){
        return new Zhang(car);
    }

    @Provides
    Wang provideWang(Car car){
        return new Wang(car);
    }

}

DemoComponent

@Component(modules = {
        CarModule.class,
        DemoModule.class
})
@CarScope   // 必须与 module provide限制相同,否则编译不通过
public interface DemoComponent {
    void inject(DemoActivity activity);
}

Activity使用

public class DemoActivity extends AppCompatActivity {
    @Inject
    Zhang zhang;
    @Inject
    Wang wang;
    @Inject
    Car car;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
        DaggerDemoComponent.create().inject(this);
        System.out.println("car --> " + car.hashCode());
    }
}
// 输出结果
我是张 我的车子对象是 -> 237250545
我是王 我的车子对象是 -> 237250545
car --> 245728614

这样也就确保了,只有一辆车

猜你喜欢

转载自blog.csdn.net/qq_30889373/article/details/81605113