本文接前一篇Dagger2入坑之旅 一
前文说到了dagger2的基本使用方法,但是乍一看却很疑惑,心中有疑惑,为什么这么写?下面一一解释
我们来重新理一遍上面的注入过程,首先弄清楚以下几个概念:
@Inject 带有此注解的属性或构造方法将参与到依赖注入中,Dagger2会实例化有此注解的类
@Module 带有此注解的类,用来提供依赖,里面定义一些用@Provides注解的以provide开头的方法,这些方法就是所提供的依赖,Dagger2会在该类中寻找实例化某个类所需要的依赖。
先看看Vehicle
的生成类 :
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class Vehicle_Factory implements Factory<Vehicle> {
private final Provider motorProvider;
public Vehicle_Factory(Provider motorProvider) {
assert motorProvider != null;
this.motorProvider = motorProvider;
}
@Override
public Vehicle get() {
return new Vehicle(motorProvider.get());
}
public static Factory create(Provider motorProvider) {
return new Vehicle_Factory(motorProvider);
}
}
检阅代码,可以看到Vehicle_Factory里有一个motorProvider的变量,get()和create方法;这里就会有疑问了为什么这个motorProvider不是’Motor’类型而是’Provider’;可以看到Vehicle是个依赖而提供这个依赖的是VehicleModule因此这个motorProvide一定是VehicleModule提供的;在看看get方法,可以发现原来Vehicle实例化是在这里进行的; 而create方法是用来创建Vehicle_Factory这个类的;
然后在看VehicleModule
生成的代码类:
由于VehicleModule这个类里实现了两个@Provides所以AS为为我们生成了两个类,因为例子里只用到了VehicleModule_ProviceVehicleFactory
所以这里只介绍这个类
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class VehicleModule_ProviceVehicleFactory implements Factory<Vehicle> {
private final VehicleModule module;
public VehicleModule_ProviceVehicleFactory(VehicleModule module) {
assert module != null;
this.module = module;
}
@Override
public Vehicle get() {
return Preconditions.checkNotNull(
module.proviceVehicle(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory create(VehicleModule module) {
return new VehicleModule_ProviceVehicleFactory(module);
}
}
可以看到VehicleModule_ProviceVehicleFactory
的 get()方法的调用VehicleModule.proviceVehicle()方法并且返回的类型是Vehicle
这个时候就很明白了,原来创建Vehicle的就是这个get()方法;
看到这里我们应该明白了Vehicle的实例化过程。Vehicle会对应的有一个工厂类,在这个类的get()方法中进行Vehicle创建,而Vehicle所需要的View依赖,是由VehicleModule里定义的以provide开头的方法所对应的工厂类提供的;
此时虽然我们明白了实例化创建,但是VehicleModule_ProviceVehicleFactory
的create()方法哪里调用的呢?此时创建的Vehicle实例是怎么跟@Inject注解的Vehicle关联起来的?这个时候就要说到 @Component了,Component是连接@Module和@Inject的桥梁,在说到VehicleComponent我们先在MainActivity里加上
@Inject
Vehicle vehicle;
然后点击make project然后AndroidStudio会为我们生成MainActivity_MembersInjector
类代码如下:
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class MainActivity_MembersInjector implements MembersInjector {
private final Provider vehicleProvider;
public MainActivity_MembersInjector(Provider vehicleProvider) {
assert vehicleProvider != null;
this.vehicleProvider = vehicleProvider;
}
public static MembersInjector create(Provider vehicleProvider) {
return new MainActivity_MembersInjector(vehicleProvider);
}
@Override
public void injectMembers(MainActivity instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.vehicle = vehicleProvider.get();
}
public static void injectVehicle(MainActivity instance, Provider vehicleProvider) {
instance.vehicle = vehicleProvider.get();
}
}
可以看到该类里有个Provider类型的参数vehicleProvider,该参数在MainActivity_MembersInjector的构造函数里被赋值;然后在看injectMembers()
方法 这个时候就很明白了MainActivity里的vehicle到底是怎么初始化了,是由vehicleProvider.get();
生成 ;
然后我们再看看VehicleComponent
生成的类 DaggerVehicleComponent
:
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class DaggerVehicleComponent implements VehicleComponent {
private Provider proviceVehicleProvider;
private MembersInjector mainActivityMembersInjector;
private DaggerVehicleComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.proviceVehicleProvider =
ScopedProvider.create(VehicleModule_ProviceVehicleFactory.create(builder.vehicleModule));
this.mainActivityMembersInjector = MainActivity_MembersInjector.create(proviceVehicleProvider);
}
@Override
public void inject(MainActivity activity) {
mainActivityMembersInjector.injectMembers(activity);
}
public static final class Builder {
private VehicleModule vehicleModule;
private Builder() {}
public VehicleComponent build() {
if (vehicleModule == null) {
throw new IllegalStateException(VehicleModule.class.getCanonicalName() + " must be set");
}
return new DaggerVehicleComponent(this);
}
public Builder vehicleModule(VehicleModule vehicleModule) {
this.vehicleModule = Preconditions.checkNotNull(vehicleModule);
return this;
}
}
}
这个时候就很清楚了,在Build类里对VehicleModule进行了创建;然后在initialize()
方法里对VehicleModule_ProviceVehicleFactory和MainActivity_MembersInjector创建,前面说过Component是连接@Module和@Inject的桥梁这里只是对他们进行了创建,并没有关联起来;真正把他们关联起来的地方在inject()
方法里 ,so在MainActivity里只要这么写就可以使用了
DaggerVehicleComponent.builder()
.vehicleModule(new VehicleModule(new Motor()))
.build()
.inject(this);
这样下来就懂了dagger2到底是怎么工作的了;只要弄懂原理,怎么使用就会明白了
Dagger2入坑之旅 三 项目实战