Dagger2的使用

简介: Dagger2的使用

Dagger2是一个依赖注入框架,我们经常用到的依赖注入框架还有ButterKnife。说到这里,首先了解一个概念:控制反转。

控制反转(又叫IOC:Inversion Of Control):是面向对象编程中的一种设计原则,可以用来降低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统的所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

说到Dagger2的使用,我们首先了解一下使用Dagger2有什么好处?

Dagger2是用来使代码解耦的,一个类的new代码是非常可能充斥在app的多个类中的,假如该类的构造函数发生变化,那这些涉及到的类都得进行修改。

1.如果使用Dagger2的Inject注解构造函数,即使构造函数发生较大的变化,我们基本上都不需要修改任何代码

2.Dagger2可以更好的帮助我们解耦   不用担心对象或者属性在被生命周期持有导致的未释放


Dagger 是通过@Inject使用具体的某个对象,这个对象呢,由@Provides注解提供,但是呢,@Provides只能在固定的模块中,也就是@Module注解,我们查找的时候,不是直接去找模块,而是去找@Component

可以这么理解 @Module 是提供你想要东西一个盒子,那么盒子是通过方法提供给你东西 但是Dagger他又不知那些方法可以提供,那么就需要在你的方法上标注一个这样的@Provides来告诉Dagger

基本使用

Dagger2,分为三部分:依赖提供方、依赖需求方、依赖注入容器(即二者之间的桥梁)。

在Dagger2中被@Module注解的类作为提供方、@Component注解的类作为桥梁、@Inject注解的变量作为需求方

@Inject注解有两个作用:

作为依赖提供方,@Inject注解添加到类的构造函数上

作为依赖需求方,@Inject注解添加到成员变量上

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

@Singleton

默认情况下,@Inject获取到的依赖对象是非单例的,要想实现单例,需要用@Singleton对Module中的provide方法和Conponent接口进行标注。

使用过程

1.导包

// dagger2
implementation 'com.google.dagger:dagger:2.23.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.23.1'

2.创建实体类并在实体类的构造方法上添加上@Inject注解,作为依赖的提供方

注意:只能有一个构造方法可以被加上@Inject注解,否则会报错

Types may only contain one @Inject constructor

public class Person {
    public String name;
    public int age;
 
    //依赖的提供方
    @Inject
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

3. 创建一个Module类

@Module
public class MainActivityModule {
    
    @Provides
    public Person providePerson(){
        return new Person("xiaowang",30);
    }
 
}

这个类的命名以Module结尾,里面针对Person类含有@Inject构造函数的参数,添加provide方法,这些provide方法需要添加@Provides注解,并且方法命名以provide开头。Module类作为依赖提供方,提供构造函数中的参数。Module 其实是一个简单工厂模式,Module 里面的方法都是创建相应类实例的方法

4.创建Component类,作为依赖提供方和依赖需求方直接的桥梁:

@Component(modules = MainActivityModule.class)
public interface MainActivityComponent {
    void inject(MainActivity mainActivity);
}

@Component一般用来注解接口,负责在@Inject@Module之间建立连接。实例化@Inject注解的时,遇到没有构造函数的类依赖,则该依赖由@Module修饰的类提供

5.在Activity中,声明一个类实例对象,并加上@Inject注解

@Inject
Person mPerson;
 
 DaggerMainActivityComponent.builder()
                .mainActivityModule(new MainActivityModule())
                .build()
                .inject(this);

获取单例对象

局部单例

在 Component类上添加@Singleton

在Module的provide方法上加上@Singleton

全局单例

在局部单例的基础上

创建Application,并在Application中创建Component

public class MyApplication extends Application {
 
    MainActivityComponent mComponent;
    @Override
    public void onCreate() {
        super.onCreate();
        mComponent = DaggerMainActivityComponent.builder().mainActivityModule(new MainActivityModule()).build();
    }
 
    public MainActivityComponent getComponent() {
        return mComponent;
    }
}

使用时,使用Application注入

((MyApplication) getApplication()).getComponent().inject(this);

所有用注解标注的类,Dagger2都会用APT在build下去生成对应的辅助类,这些辅助类的名字是根据dagger-compiler注解依赖库中的命名规则生成的。

手动创建 APT生成 命名规则 注解
MainActivity MainActivity_MembersInjector 类名_MembersInjector @Inject
TwoActivity TwoActivity_MembersInjector 类名_MembersInjector

@Inject

MainActivityComponent DaggerMainActivityComponent Dagger对象名Component @Component
MainActivityModule MainActivityModule_ProvidePersonFactory 对象名Module_方法名Factory @Module @Provides
Person Person_Factory 对象名_Factory @Inject

 

 
public final class DaggerMainActivityComponent implements MainActivityComponent {
  private Provider<Person> providePersonProvider;
 
  private DaggerMainActivityComponent(MainActivityModule mainActivityModuleParam) {
 
    initialize(mainActivityModuleParam);
  }
 
  //使用构造者模式实例化DaggerMainActivityComponent对象
  public static Builder builder() {
    return new Builder();
  }
 
  public static MainActivityComponent create() {
    return new Builder().build();
  }
 
  @SuppressWarnings("unchecked")
  private void initialize(final MainActivityModule mainActivityModuleParam) {
    this.providePersonProvider = DoubleCheck.provider(MainActivityModule_ProvidePersonFactory.create(mainActivityModuleParam));
  }
 
  @Override
  public void inject(MainActivity mainActivity) {
    injectMainActivity(mainActivity);}
 
  @Override
  public void injectTwo(TwoActivity twoActivity) {
    injectTwoActivity(twoActivity);}
  //4 Activity中的@Inject生成injectMainActivity方法,通过MainActivityModule_ProvidePersonFactory来获取依赖注入对象
  private MainActivity injectMainActivity(MainActivity instance) {
    MainActivity_MembersInjector.injectMPerson(instance, providePersonProvider.get());
    MainActivity_MembersInjector.injectMPerson1(instance, providePersonProvider.get());
    return instance;
  }
 
  private TwoActivity injectTwoActivity(TwoActivity instance) {
    TwoActivity_MembersInjector.injectMPerson(instance, providePersonProvider.get());
    return instance;
  }
 
  public static final class Builder {
    private MainActivityModule mainActivityModule;
 
    private Builder() {
    }
    //2 传入MainActivityModule对象
    public Builder mainActivityModule(MainActivityModule mainActivityModule) {
      this.mainActivityModule = Preconditions.checkNotNull(mainActivityModule);
      return this;
    }
    //3 实例化DaggerMainActivityComponent
    public MainActivityComponent build() {
      if (mainActivityModule == null) {
        this.mainActivityModule = new MainActivityModule();
      }
      return new DaggerMainActivityComponent(mainActivityModule);
    }
  }
}
public final class MainActivityModule_ProvidePersonFactory implements Factory<Person> {
  private final MainActivityModule module;
 
  public MainActivityModule_ProvidePersonFactory(MainActivityModule module) {
    this.module = module;
  }
 
  @Override
  public Person get() {
    return providePerson(module);
  }
 
  public static MainActivityModule_ProvidePersonFactory create(MainActivityModule module) {
    return new MainActivityModule_ProvidePersonFactory(module);
  }
  //5 通过MainActivityModule拿到Person对象,并用Dagger2提供的Preconditions.checkNotNull()方法来检查获取到的对象是否为空
  public static Person providePerson(MainActivityModule instance) {
    return Preconditions.checkNotNull(instance.providePerson(), "Cannot return null from a non-@Nullable @Provides method");
  }
}
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
  private final Provider<Person> mPersonAndMPerson1Provider;
 
  public MainActivity_MembersInjector(Provider<Person> mPersonAndMPerson1Provider) {
    this.mPersonAndMPerson1Provider = mPersonAndMPerson1Provider;
  }
 
  public static MembersInjector<MainActivity> create(Provider<Person> mPersonAndMPerson1Provider) {
    return new MainActivity_MembersInjector(mPersonAndMPerson1Provider);}
 
  @Override
  public void injectMembers(MainActivity instance) {
    injectMPerson(instance, mPersonAndMPerson1Provider.get());
    injectMPerson1(instance, mPersonAndMPerson1Provider.get());
  }
  //6 将获取到的Person对象赋值给Activity中的mPerson
  public static void injectMPerson(MainActivity instance, Person mPerson) {
    instance.mPerson = mPerson;
  }
 
  public static void injectMPerson1(MainActivity instance, Person mPerson1) {
    instance.mPerson1 = mPerson1;
  }
}
目录
相关文章
|
3月前
|
Android开发
解決Android报错:Could not initialize class org.codehaus.groovy.reflection.ReflectionCache
解決Android报错:Could not initialize class org.codehaus.groovy.reflection.ReflectionCache
108 1
|
缓存 Android开发 开发者
Dagger2 框架与 SystemUI
Dagger2 框架与 SystemUI
Dagger2 框架与 SystemUI
|
缓存 Android开发 开发者
Dagger2和它在SystemUI上的应用
Dagger2和它在SystemUI上的应用
Dagger2和它在SystemUI上的应用
|
存储 前端开发 Java
Jetpack 系列(10)—— 从 Dagger2 到 Hilt 玩转依赖注入(一)
Jetpack 系列(10)—— 从 Dagger2 到 Hilt 玩转依赖注入(一)
440 0
Jetpack 系列(10)—— 从 Dagger2 到 Hilt 玩转依赖注入(一)
Android | 依赖注入与 Dagger2 框架【@Deprecated】
Android | 依赖注入与 Dagger2 框架【@Deprecated】
209 0
Android | 依赖注入与 Dagger2 框架【@Deprecated】
|
Android开发
Failed to transform artifact 'butterknife-runtime.aar (com.jakewharton:butterknife-runtime:10.1.0)'
Failed to transform artifact 'butterknife-runtime.aar (com.jakewharton:butterknife-runtime:10.1.0)'
CoreLocation第三方框架
CoreLocation第三方框架
119 0
CoreLocation第三方框架
|
存储 设计模式 前端开发
依赖注入之Dagger2初探
依赖注入之Dagger2初探
234 0
|
Java Maven Android开发
Dagger2 入门解析
前言 在为dropwizard选择DI框架的时候考虑了很久。Guice比较成熟,Dagger2主要用于Android。虽然都是google维护的,但Dagger2远比guice更新的频率高。再一个是,Dagger2不同于guice的运行时注入,编译时生成代码的做法很好。
2016 0
|
测试技术 Android开发 数据格式
Android Dagger2依赖注入
Dagger2项目主页 使用依赖 annotationProcessor 'com.google.dagger:dagger-compiler:2.
1039 0