前言
想着把学习的东西记录下来,能更好的巩固;
第一次写csdn,相信会越来越好;
dagger2的引用
(在build.gradle(Moudle)配置)
dependencies {
implementation 'com.google.dagger:dagger:2.21'
implementation 'com.google.dagger:dagger-android:2.35.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.21'
}
简单实用
注解
-
@Inject:如果在类上添加此依赖注入,Dagger 就会构造一个这个类的实例并满足他们的依赖。
通过这个inject注解可以将依赖需求方对象送到Component类中,Component类就会根据依赖需求方对象中声明的依赖关系来注入依赖需求方对象中所需要的对象,注意:inject方法的参数不能用父类来接收,@Inject注解的字段不能是private和protected的。 -
@Module:编写Module类时要在该类上声明@Module以表明该类是Module类,这样Dagger2才能识别,Modules 类里面的方法专门提供依赖,如返回你需要依赖的对象实例。
-
@Provide:在 modules 中我们定义的方法就用@Provide注解,作用是声明Module类中哪些方法是用来提供依赖对象的,当Component类需要依赖对象时,他就会根据返回值的类型来在有@Provides注解的方法中选择调用哪个方法。
-
@Singleton:实现单例
-
@Component:Components 从根本上来说就是一个注入器,也可以说是@Inject 和@Module 的桥梁,来连接@Inject 和@Module这两个部分。但@Component注解的作用可不是单单用来声明Component类,@Component注解有modules和dependencies两个属性,这两个属性的类型都是Class数组,modules的作用就是声明该Component含有哪几个Module;而dependencies属性则是声明Component类的依赖关系,这个我们之后详细讲解。
实际应用
想象快递员送快递的过程
创建物品
(快递员送的物品,我这里的Student就是物品)
/**
* 物品
*/
public class Student {
Student() {
}
}
打包
(创建物品后要进行打包处理)
/**
* 包裹
*/
@Module
public class StudentModule {
@Provides // 暴露我们的物品
public Student getStudent() {
return new Student();
}
}
快递员
(交给快递员来送-依赖)
/**
* 快递员
*/
@Component(modules = StudentModule.class)
public interface StudentComponent {
// 收货地址 用户的地址 注入进来 MainActivity
void injectMainActivity (MainActivity mainActivity);
}
当然快递员也可以拿多个包裹(这里又加入一个Book包裹)
/**
* 快递员
*
*/
@Component(modules = {StudentModule.class, BookModule.class})
// 快递员是不是可以 有多个包裹
public interface StudentComponent {
// 收货地址 用户的地址 注入进来 MainActivity
void injectMainActivity (MainActivity mainActivity);
}
快递接受者
(注入)
public class MainActivity extends AppCompatActivity {
private String TAG = "RGY";
@Inject
Student student;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerStudentComponent.create().injectMainActivity(this);//注入
Log.d(TAG, "student.hashCode()->" + student.hashCode());
}
}
打印结果为:student.hashCode()->78447935
现在我们改一下,多加一个引入
public class MainActivity extends AppCompatActivity {
private String TAG = "RGY";
@Inject
Student student;//private 会报错
@Inject
Student student1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerStudentComponent.create().injectMainActivity(this);
Log.d(TAG, "student.hashCode()->"+student.hashCode() );
Log.d(TAG, "student1.hashCode()->"+student.hashCode() );
}
}
打印结果:
student.hashCode()->78447935 student1.hashCode()->50241036
会发现hashCode值不同,也就是它不是单例,接下来把它改为单例
单例
只需要在包裹和快递员上加上@Singleton
/**
* 包裹
*/
@Module
public class StudentModule {
@Singleton
@Provides // 暴露我们的物品
public Student getStudent() {
return new Student();
}
}
/**
* 快递员
*
*/
@Singleton
@Component(modules = {StudentModule.class, BookModule.class})// 快递员是不是可以 有多个包裹
public interface StudentComponent {
// 收货地址 用户的地址 注入进来 MainActivity
void injectMainActivity (MainActivity mainActivity);
}
然后运行打印结果为:
student.hashCode()->85101918
student1.hashCode()->85101918
是不是已经一样了,但是在不同的activity中还是会出现非单例现象
打印结果为:(student2是另一个activity的student引用)
student.hashCode()->194965557
student1.hashCode()->194965557
student2.hashCode()->199463780
解决方法:
在application中注册
public class MyApplication extends Application {
private StudentComponent StudentComponent;
@Override
public void onCreate() {
super.onCreate();
// 方式二 使用注解处理器生成代码的细节,来完成的
StudentComponent= DaggerStudentComponent.builder()
.studentModule(new StudentModule())
.bookModule(new BookModule())
.build();
}
public StudentComponent getStudentComponent(){
return StudentComponent;
}
}
然后在activity中引用application中的方法,达到统一
setContentView(R.layout.activity_main);
//DaggerStudentComponent.create().injectMainActivity(this);
//用MyApplication里面的来进行注入
((MyApplication)getApplication())
.getStudentComponent()
.injectMainActivity(this);
Log.d(TAG, "student.hashCode()->"+student.hashCode() );
Log.d(TAG, "student1.hashCode()->"+student1.hashCode() );
Log.d(TAG, "book.hashCode()->"+book.hashCode() );
//跳转进入另一个Activity
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this, MainActivity2.class));
}
});
}
}
打印结果为:
student.hashCode()->194965557
student1.hashCode()->194965557
student2.hashCode()->194965557
这就完成了全局单例