欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Dagger2的使用

程序员文章站 2022-03-28 12:46:13
一.@Inject1.用户自定义的类在构造函数使用@Inject注解。public class Student { @Inject public Student(){ }}2.新建一个接口,名称一般以Activity名称加Component组成,使用@Component修饰,其中包含一个injectTo方法,表示将对象注入到某个类中。@Componentpublic interface Test1ActivityComponent { void injectT...

一.@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());
    }
}

本文地址:https://blog.csdn.net/wby371427/article/details/107924388

相关标签: Android