Dagger2的使用

一.@Inject
1.用户自定义的类在构造函数使用@Inject注解。
public class Student {
    @Inject
    public Student(){

    }
}
2.新建一个接口,名称一般以Activity名称加Component组成,使用@Component修饰,其中包含一个injectTo方法,表示将对象注入到某个类中。
@Component
public interface Test1ActivityComponent {
    void injectTo(Test1Activity activity);
}
3.在Activity中新建成员变量student,并用@Inject修饰,student不能是private。
public class Test1Activity extends AppCompatActivity {
    @Inject
    Student student;
}
4.点击编译按钮,在/build/generated/ap_generated_sources/debug/out文件夹下会生成代码,其中,被@Inject修饰的构造函数会生成"类名_Factory",如:Student_Factory,该类实现Factory接口,通过工厂生产Student对象。
public final class Student_Factory implements Factory<Student> {
  private static final Student_Factory INSTANCE = new Student_Factory();

  @Override
  public Student get() {
    return new Student();
  }
//单例模式
  public static Student_Factory create() {
    return INSTANCE;
  }

  public static Student newInstance() {
    return new Student();
  }
}
Activity中被@Inject修饰的成员变量生成的类为:Test1Activity_MembersInjector。
public final class Test1Activity_MembersInjector implements MembersInjector<Test1Activity> {
  private final Provider<Student> studentProvider;

  public Test1Activity_MembersInjector(Provider<Student> studentProvider) {
    this.studentProvider = studentProvider;
  }

  public static MembersInjector<Test1Activity> create(Provider<Student> studentProvider) {
    return new Test1Activity_MembersInjector(studentProvider);}

  @Override
  public void injectMembers(Test1Activity instance) {
    injectStudent(instance, studentProvider.get());
  }
	//通过类名+成员变量赋值,所以instance的成员变量不能为private
  public static void injectStudent(Test1Activity instance, Student student) {
    instance.student = student;
  }
}
被@Component修饰的Test1ActivityComponent会生成实现类DaggerTest1ActivityComponent。
public final class DaggerTest1ActivityComponent implements Test1ActivityComponent {
  private DaggerTest1ActivityComponent() {

  }
	//通过Builder生成对象
  public static Builder builder() {
    return new Builder();
  }

  public static Test1ActivityComponent create() {
    return new Builder().build();
  }
	//injectTo方法的实现
  @Override
  public void injectTo(Test1Activity activity) {
    injectTest1Activity(activity);}

  private Test1Activity injectTest1Activity(Test1Activity instance) {
	//直接new Student()进行注入
    Test1Activity_MembersInjector.injectStudent(instance, new Student());
    return instance;
  }

  public static final class Builder {
    private Builder() {
    }

    public Test1ActivityComponent build() {
      return new DaggerTest1ActivityComponent();
    }
  }
}
5.在Activity的onCreate方法中调用DaggerTest1ActivityComponent.create().injectTo(this),为成员变量赋值。
二.@Module
1.对于第三方库提供的类,无法为其构造方法添加@Inject,此时新建一个类如Test2ActivityModule:
@Module
public class Test2ActivityModule {
    @Provides
    Thread threadProvides(){
        return new Thread();
    }
    @Provides
    List<String> listProvides(){
        return new ArrayList<>();
    }
}
编译时对于每个@Provides会生成Factory工厂类,如Test2ActivityModule_ListProvidesFactory:
public final class Test2ActivityModule_ListProvidesFactory implements Factory<List<String>> {
  private final Test2ActivityModule module;

  public Test2ActivityModule_ListProvidesFactory(Test2ActivityModule module) {
    this.module = module;
  }

  @Override
  public List<String> get() {
    return listProvides(module);
  }

  public static Test2ActivityModule_ListProvidesFactory create(Test2ActivityModule module) {
    return new Test2ActivityModule_ListProvidesFactory(module);
  }
	//通过该方法生成类的实例,此处的instance就是Test2ActivityModule
  public static List<String> listProvides(Test2ActivityModule instance) {
    return Preconditions.checkNotNull(instance.listProvides(), "Cannot return null from a non-@Nullable @Provides method");
  }
}
2.在Component中指定Module
@Component(modules = Test2ActivityModule.class)
public interface Test2ActivityComponent {
    void injectTo(Test2Activity activity);
}
在调用injectTo方法时,注入的对象是由Module生产的
  @Override
  public void injectTo(Test2Activity activity) {
    injectTest2Activity(activity);
  }

  private Test2Activity injectTest2Activity(Test2Activity instance) {
    Test2Activity_MembersInjector.injectList(instance, Test2ActivityModule_ListProvidesFactory.listProvides(test2ActivityModule));
    Test2Activity_MembersInjector.injectThread(instance, Test2ActivityModule_ThreadProvidesFactory.threadProvides(test2ActivityModule));
    return instance;
  }
三.为Test3ActivityModule传参
1.Module中生产的对象如果构造函数需要传值,如Button,需要为其传递context,则Module如下:
@Module
public class Test3ActivityModule {
    private Context context;

    public Test3ActivityModule(Context context) {
        this.context = context;
    }
    @Provides
    Button buttonProvides(){
        return new Button(context);
    }
}
2.编译之后Activity的写法如下:
public class Test3Activity extends AppCompatActivity {
    @Inject
    Button button;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    //    DaggerTest3ActivityComponent.builder()中会生成test3ActivityModule方法,接收一个Module对象,此时不会生成create方法,只能通过builder().build构建DaggerTest3ActivityComponent。
        DaggerTest3ActivityComponent.builder().test3ActivityModule(new Test3ActivityModule(this)).build().injectTo(this);
        System.out.println(button);
    }
}
四.@Component.Builder
DaggerTestActivityComponent.Builder类也可由用户自己定义,写法如下:
@Component(modules = Test4ActivityModule.class)
public interface Test4ActivityComponent {
    void injectTo(Test4Activity activity);
    @Component.Builder
    interface Builder{
        Builder test4ActivityModule(Test4ActivityModule test4ActivityModule);
        Test4ActivityComponent build();
    }
}
经过编译后生成的DaggerTest4ActivityComponent代码与三相同,只是DaggerTest4ActivityComponent.Builder类实现了Test4ActivityComponent.Builder接口。
五.@BindsInstance
第三方库的类构造函数需要传参时,可以通过Component初始化,Module如下,此时Module的构造方法没有接收参数:
@Module
public class Test5ActivityModule {

    @Provides
    Button buttonProvides(Context context){
        return new Button(context);
    }
    @Provides
    Thread threadProvides(Runnable runnable){
        return new Thread(runnable);
    }
}
Component如下,Builder中提供初始化方法用来传递Module生产对象所需的参数:
@Component(modules = Test5ActivityModule.class)
public interface Test5ActivityComponent {
    void injectTo(Test5Activity activity);
    @Component.Builder
    interface Builder{
        @BindsInstance
        Builder initButton(Context context);
        Test5ActivityComponent build();
        @BindsInstance
        Builder initThread(Runnable runnable);
    }
}
编译后调用如下:
public class Test5Activity extends AppCompatActivity {
    @Inject
    Button button;
    @Inject
    Thread thread;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
	//在此处传递参数        
        DaggerTest5ActivityComponent.builder().initButton(this).initThread(new Runnable() {
            @Override
            public void run() {

            }
        }).build().injectTo(this);
        System.out.println(button);
    }
}
六.dependencies
当Activity和Fragment需要注入相同的对象时,Fragment可以依赖Activity的Module生产对象,此时需要使用dependencies。Activity的Module、Component如下:
@Module
public class Test6ActivityModule {

    @Provides
    Button buttonProvides(Context context){
        return new Button(context);
    }
    @Provides
    Thread threadProvides(Runnable runnable){
        return new Thread(runnable);
    }
}

@Component(modules = Test6ActivityModule.class)
public interface Test6ActivityComponent {
    void injectTo(Test6Activity activity);
    Button provideButton();
    Thread provideThread();
    @Component.Builder
    interface Builder{
        @BindsInstance
        Builder initButton(Context context);
        Test6ActivityComponent build();
        @BindsInstance
        Builder initThread(Runnable runnable);
    }
}
Fragment不需要Module,其Component如下:
//此处使用dependencies,依赖Activity的Component
@Component(dependencies = Test6ActivityComponent.class)
public interface Test6FragmentComponent {
    void injectTo(Test6Fragment fragment);
}
Activity需要将component提供给Fragment。
public class Test6Activity extends AppCompatActivity {
    @Inject
    Button button;
    @Inject
    Thread thread;
    Test6ActivityComponent component;
	//提供get方法供Fragment使用
    public Test6ActivityComponent getComponent() {
        return component;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //与之前相同
        component = DaggerTest6ActivityComponent.builder().initButton(this)
                .initThread(new Runnable() {
                    @Override
                    public void run() {

                    }
                })
                .build();
        component.injectTo(this);
        //添加Fragment
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = manager.beginTransaction();
        fragmentTransaction.add(new Test6Fragment(),"test6").commitAllowingStateLoss();

    }
}

public class Test6Fragment extends Fragment {
    @Inject
    Button button;
    @Inject
    Thread thread;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Test6ActivityComponent component = ((Test6Activity)getActivity()).getComponent();
        //拿到Activity的Component并交给FragmentComponent,Fragment中需要的对象就由Activity的Component和Module生产。
        DaggerTest6FragmentComponent.builder()
                .test6ActivityComponent(component)
                .build().injectTo(this);
        System.out.println(button);
        System.out.println(thread);
        return super.onCreateView(inflater, container, savedInstanceState);
    }
}
七. @Subcomponent
六中的效果可以通过@Subcomponent实现,Fragment的Component的如下:
//表示该Component为子Component
@Subcomponent
public interface Test7FragmentComponent {
    void injectTo(Test7Fragment fragment);
}
Activity的Component如下:
@Component(modules = Test7ActivityModule.class)
public interface Test7ActivityComponent {
    void injectTo(Test7Activity activity);
    //把子Component添加进来
    Test7FragmentComponent test7FragmentComponent();
    @Component.Builder
    interface Builder{
        @BindsInstance
        Builder initButton(Context context);
        Test7ActivityComponent build();
        @BindsInstance
        Builder initThread(Runnable runnable);
    }
}
Fragment使用如下:
public class Test7Fragment extends Fragment {
    @Inject
    Button button;
    @Inject
    Thread thread;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Test7ActivityComponent component = ((Test7Activity)getActivity()).getComponent();
        //获取ActivityComponent的子Component,即FragmentComponent
        component.test7FragmentComponent().injectTo(this);
        return super.onCreateView(inflater, container, savedInstanceState);
    }
}
八.@Named
@Named用来区分相同类的不同实例
@Module
public class Test9ActivityModule {
	//提供同一个类的不同对象,使用@Named区分
    @Named("one")
    @Provides
    Student provideOne(){
        return new Student("One",1);
    }
    @Named("two")
    @Provides
    Student provideTwo(){
        return new Student("Two",2);
    }
}

public class Test9Activity extends AppCompatActivity {
    @Named("one")//对应Module中的@Named
    @Inject
    Student oneStudent;
    @Named("two")
    @Inject
    Student twoStudent;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerTest9ActivityComponent.create().injectTo(this);
        System.out.println(oneStudent);//Student("One",1)
        System.out.println(twoStudent);//Student("Two",2)
    }
}
九.@Singleton
@Singleton表示类为单例,此处的单例是局域性的,Component的build如果在Activity执行,那么这个类在Activity里是单例,如果退出该Activity再进入,这个类会被重新生成;Component的build如果在Application执行,那么该类在Application的生命周期内是单例。
@Singleton在Module的@Provides和@Component之前使用。
@Module
public class Test10ActivityModule {
    @Singleton
    @Provides
    Thread threadProvides(){
        return new Thread();
    }
    @Singleton
    @Provides
    List<String> listProvides(){
        return new ArrayList<>();
    }
}

@Singleton
@Component(modules = Test10ActivityModule.class)
public interface Test10ActivityComponent {
    void injectTo(Test10Activity activity);
}

public class Test10Activity extends AppCompatActivity {
    @Inject
    List<String> list;
    @Inject
    Thread thread1;
    @Inject
    Thread thread2;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerTest10ActivityComponent.create().injectTo(this);
        //此处thread1和thread2是同一个对象
        System.out.println(thread1.hashCode());
        System.out.println(thread2.hashCode());
    }
}
十.全局单例
全局单例就是Component在Application中build。
@Module
public class ApplicationModule {
    @Singleton
    @Provides
    Student provideStudent(){
        return new Student();
    }
}

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
    Student provideStudent();
}

public class MyApplication extends Application {
    ApplicationComponent component;

    public ApplicationComponent getComponent() {
        return component;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //在在Application中build并对外提供。
        component = DaggerApplicationComponent.builder().build();
    }
}

public class Test10Activity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //获取ApplicationComponent
        ApplicationComponent component = ((MyApplication)getApplication()).getComponent();
        Student student = component.provideStudent();
        System.out.println(student.hashCode());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值