- 在android引入Dagger2库
//引入Dagger2implementation("com.google.dagger:dagger:2.48.1")annotationProcessor ("com.google.dagger:dagger-compiler:2.48.1")
- 构造器注入
创建一个类
public class Car {//在构造器上面添加dagger的@Inject即可@Injectpublic Car() {Log.e("car", "new Car " + this);}}
创建注入器
//调用dagger的@Component注解
@Component
public interface MainComponent {//哪个个类需要注入,这里是MainActivity需要注入含有@Inject的类void inject(MainActivity mainActivity);
}
初始化注入器
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.e("MainActivity", "new onCreate");//dagger会自动生成一个Dagger+创建的接口名称的类,初始化注入器DaggerMainComponent.create().inject(this);}
开始注入对象
//定义需要被注入的实例,在变量中定义注解@Injet即可,这样就会创建一个实例//这里相当于DaggerMainComponent.create().inject(this);car=new Car();@InjectCar car;
打印log如下
多次调用会注入多个不同对象,想到于创建了多个不同对象
@InjectCar car;@InjectCar car1;@InjectCar car2;
打印log如下,创建了多个对象
- 有参数构造器注入
这了创建两个类
public class CarA {private Car car;@Injectpublic CarA(Car car) {this.car = car;Log.e("car", "new CarA " + this);}
}
public class CarB {private Car car;private CarA carA;@Injectpublic CarB(CarA carA,Car car) {this.car = car;this.carA = carA;Log.e("car","new CarB "+this);}
}
我们直接在MainActivity中注入CarB
@InjectCarB carB;
猜猜会创建多少个对象
结果如下
现在理一下思路
@Inject CarB carB;
相当于
CarB carB=new CarB(CarA carA,Car car)
这两个参数是怎么来的呢,我们在CarA的构造器上面有@Inject,这边代码会帮我们进行创建CarA,进一步代码会变成如下
CarB carB=CarB(new CarA(Car car) ,Car car) ;
Car 又是哪里来的呢,我们在Car的构造器上有@Inject,代码会帮我们创建对应对象,所以进一步为
CarB carB=CarB(new CarA(new Car()) ,new Car()) ;
所以打印是上面那个流程
- 无法在构造器上使用@Injet创建方法
我们在不是自己创建的类上无法在构造器上进行@Injec注解,那该怎么使用了,dagger提供了另一个注解方式@Module+@Provides实现,下面以Retrofit创建为例
引入Retrofit
val retrofit2 = "2.9.0"implementation("com.squareup.retrofit2:retrofit:$retrofit2")
创建如下
创建Retrofit的接口类
public interface ApiService {
}第一个步:Dagger提供实例化Module//使用@Module,表示这个类是个Dagger的Module,同时我们需要把这个类载入带有@Component注解的接口中
@Module
public class NetMoudle {//外部引用的类无法在构造方法上增加@Inject,通过@Privides方法进行创建对象@Providespublic Retrofit provideRetrofit() {Retrofit retrofit = new Retrofit.Builder().baseUrl("http://www.baidu.com").build();Log.e("NetModule", "new Retrofit" + retrofit);return retrofit;}//通过参数传入在Module中创建的值,这里代码执行相当于provideApiService(provideRetrofit()),调用了provideRetrofit()//方法传入参数@Providespublic ApiService provideApiService(Retrofit retrofit) {ApiService apiService = retrofit.create(ApiService.class);Log.e("NetModule", "new ApiService retrofit " + retrofit);Log.e("NetModule", "new ApiService " + apiService);return apiService;}
}第二步:装载
//调用dagger的@Component注解,这个里面可以创建多个注解
@Component(modules = {NetMoudle.class})
public interface MainComponent {//哪个个类需要注入,这里是MainActivity需要注入含有@Inject的类void inject(MainActivity mainActivity);
}
接下来就是调用
@InjectRetrofit retrofit;@InjectApiService apiService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.e("MainActivity", "new onCreate");//dagger会自动生成一个Dagger+创建的接口名称的类,初始化注入器DaggerMainComponent.create().inject(this);}
再猜猜会是什么打印呢
再次来看看是什么创建逻辑
首先
@Inject Retrofit retrofit;
相当于代码自动调用了
NetMoudle().provideRetrofit()
所以这里打印了一个实例化Retrofit,会打印第二行
紧接着
@Inject ApiService apiService;
相当于
NetMoudle().provideApiService(NetMoudle().provideRetrofit())
这里会打印后面的log。在provideApiService方法中获取到的Retrofit是从provideRetrofit()获取到的,两个Retrofit的地址相同。
这里发现不管是从@Inject注解到构造器上,还是通过@Privodes注解方法实现实例化类,都会创建多个对象,但是在项目中,有些类需要用到单利模式,那该怎么办呢,接下来就要用到Dagger2的作用域了,下面是作用域的讲解
- 局部作用域