Dagger2使用详解

注解分类:@Inject、@Module、@Provides、@Component、@Qualifier、@Scope、@Singleten。

1. 通过@Inject生成实例生成,并通过@Inject注入。

  • @Inject 有两个作用,一是通过Moudle中@Provider定义方法提供实例,二是当@Inject标记构造方法时会提供依赖,注入到@Inject 注解的变量当中,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Car {

    @Inject
    Engine engine;

    public Car() {
    DaggerCarComponent.builder().build().inject(this);
    }

    public Engine getEngine() {
    return this.engine;
    }
    }

    @Inject 注解同样可以实现不带参数构造方法生成实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Engine {

    @Inject
    Engine(){}

    public void run(){
    System.out.println("引擎转起来了~~~");
    }
    }
  • @Component

    1
    2
    3
    4
    @Component(modules = {CarModule.class})
    public interface CarComponent {
    void inject(Car car);
    }

2. 通过@Module和@Providers提供实例,@Inject实现注入。

@Module:@Module用于标注提供依赖的类。你可能会有点困惑,上面不是提到用@Inject标记构造函数就可以提供依赖了么,为什么还需要@Module?很多时候我们需要提供依赖的构造函数是第三方库的,我们没法给它加上@Inject注解,又比如说提供以来的构造函数是带参数的,如果我们只简单的使用@Inject标记它,那么他的参数又怎么来呢?@Module正是帮我们解决这些问题的。

  • @Module 和 @Provides,@Inject 注释的参数类型和Module中方法的返回值相关联。在方法中要使用@Qualifier注解区分相同返回类型的方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Engine {

    private String name;

    public Engine(String name) {
    System.out.println("Create Engine");
    this.name = name;
    }

    public void run() {
    System.out.println(name + " 引擎转起来了~~~");

    }
    }

    @Provides:@Provides用于标注Module所标注的类中的方法,该方法在需要提供依赖时被调用,从而把预先提供好的对象当做依赖给标注了@Inject的变量赋值;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @Module
    public class CarModule {

    public CarModule() {}

    @Provides
    Engine providerEngine() {
    return new Engine("gear");
    }

    @QualifierA
    @Provides
    Engine provideEngineA(){
    return new Engine("gearA");
    }

    @QualifierB
    @Provides
    Engine provideEngineB(){
    return new Engine("gearB");
    }
    }
  • @Qualifier 实现指定注入的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    public @interface QualifierA {
    }

    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    public @interface QualifierB {
    }

3. 通过@Scope和@Singleton实现局部或全局单例

  • @Scope

    1
    2
    3
    4
    5
    // 局部单例元注解
    @Scope
    @Retention(RetentionPolicy.RUNTIME)
    public @interface CarScope {
    }

@Binds

主要作用就是确定接口与具体的具体实现类,这样说得比较抽象,我们还是看看例子吧。
在DishesFragment中有这么一句代码:

Dagger2 错误提示

1
错误: [Dagger/MissingBinding] com.markzl.android.githubclient.ui.welcome.WelcomeViewModel cannot be provided without an @Inject constructor or an @Provides-annotated method.

提示缺少部分注入数据,如 ViewModel 是通过 ViewModelFactory 创建返回,如果ViewModelFactory没有被注入数据,那么控制台会打印上述错误信息。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×