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