Dagger2学习篇——简单使用
Dagger2学习篇——注入原理
Dagger2学习篇——2.11版本后代码简化及原理分析
简化的过程需要引入AndroidInjectionModule到项目中:(参考Dagger2 github)
dependencies {
compile 'com.google.dagger:dagger-android:2.x'
compile 'com.google.dagger:dagger-android-support:2.x' // if you use the support libraries
annotationProcessor 'com.google.dagger:dagger-android-processor:2.x'
}
在上一篇:【Dagger2学习篇——注入原理】的基础上进一步修改并分析。
Dagger2.11以上版本代码简化修改
// Activity代码
public class Main3Activity extends Activity implements Main3Contract.View {
@Inject
Main3Presenter mainPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainPresenter.attachView(this);
mainPresenter.loadData();
}
@Override
public void updateUI() {
Toast.makeText(this, "Dagger2 Android 回调啦", Toast.LENGTH_SHORT).show();
}
}
// Presenter代码
public class Main3Presenter {
private Main3Contract.View mView;
@Inject
public Main3Presenter() {}
public void attachView(Main3Contract.View view) {
this.mView = view;
}
public void loadData() {
// ......
mView.updateUI();
}
}
// Contact代码
public class MainContract {
interface View {
void updateUI();
}
}
// Module
@Module
public abstract class ActivityBindingModule {
@ActivityScoped
@ContributesAndroidInjector()
abstract Main3Activity main3ActivityInjector();
}
// Component
@Singleton
@Component(modules = {
ActivityBindingModule.class,
AndroidInjectionModule.class
})
interface AppComponent extends AndroidInjector<Main3Application> {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<Main3Application> {}
}
// Application
public class Main3Application extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.builder().create(this);
}
}
在 Presenter 中不再使用构造函数来设置 View,而是使用 attachView 的方式来设置。
将原先的 module 和 component 都去掉,改用 AppComponent 和 ActivityBindingModule 统一对 Activity 的依赖注入进行管理。
工作原理
Main3Application
public class Main3Application extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.builder().create(this);
}
}
继承自 DaggerApplication,App 启动之后的依赖注入工作交给 DaggerApplication 来处理,这里的 create 方法实际上是其子类AndroidInjector 中的方法,用于构建 AndroidInjector<T>。
DaggerApplication
public abstract class DaggerApplication extends Application
implements HasActivityInjector, ……// 其它四大组件和fragment接口省略 {
……
// 其它四大组件和fragment接口省略
@Inject DispatchingAndroidInjector<Activity> activityInjector;
private volatile boolean needToInject = true;
@Override
public void onCreate() {
super.onCreate();
injectIfNecessary();
}
/** 返回一个AndroidInjector<DaggerApplication>,其注入器是Component */
@ForOverride
protected abstract AndroidInjector<? extends DaggerApplication> applicationInjector();
private void injectIfNecessary() {
…… // 懒加载
// 这里的实现位于Main3Application
AndroidInjector<DaggerApplication> applicationInjector =
(AndroidInjector<DaggerApplication>) applicationInjector();
applicationInjector.inject(this);
……
}
@Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return activityInjector;
}
……// 其它四大组件和fragment接口省略
}
App 初始化时,在需要注入的时候,通过 applicationInjector.inject(this) 来实现依赖注入。同时提供了四大组件及 Fragment 的注解分发器 DispatchingAndroidInjector<T>。
由于接下来要分析的 applicationInjector 是由 DaggerAppComponent 构建并返回的,DaggerAppComponent 是 Dagger2 生成的AppComponent 依赖注入具体实现类。另外 DaggerAppComponent 的继承关系:DaggerAppComponent => AppComponent => AndroidInjector,所以先分析后面两个类。
AppComponent
@Singleton
@Component(modules = {
ActivityBindingModule.class,
AndroidInjectionModule.class
})
interface AppComponent extends AndroidInjector<Main3Application> {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<Main3Application> {}
}
Component 的作用:将对象注入到使用者之中。
AndroidInjector
public interface AndroidInjector<T> {
void inject(T instance);
/**
* Creates {@link AndroidInjector}s for a concrete subtype of a core Android type.
* @param <T> the concrete type to be injected
*/
interface Factory<T> {
AndroidInjector<T> create(T instance);
}
abstract class Builder<T> implements AndroidInjector.Factory<T> {
@Override
public final AndroidInjector<T> create(T instance) {
seedInstance(instance);
return build();
}
/** 提供构建AndroidInjector时需要使用的实例。*/
@BindsInstance
public abstract void seedInstance(T instance);
/** 返回一个具体的AndroidInjector */
public abstract AndroidInjector<T> build();
}
}
AndroidInjector 定义了一个 inject 方法实现注入;定义了一个工厂类,用来创建该对象,返回一个具体 AndroidInjector<T>,这里的T的实例由 seedInstance 方法来构建。(面向接口编程,移除被注入者对注入者的依赖)
这里调用 create 传入需要注入的目标对象,并通过 seedInstance 设置所需注入的目标对象的实例,然后再调用 build 方法返回一个 DaggerAppComponent 对象。
DaggerAppComponent
public final class DaggerAppComponent implements AppComponent {
private Provider<ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent.Builder>
main3ActivitySubcomponentBuilderProvider;
private DaggerAppComponent(Builder builder) {
initialize(builder); // 5
}
public static AppComponent.Builder builder() {
return new Builder(); // 1 通过AndroidInjector的工厂类创建
}
private Map<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>>
getMapOfClassOfAndProviderOfFactoryOf() { // 9.4
return Collections.<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>> singletonMap(
Main3Activity.class, (Provider) main3ActivitySubcomponentBuilderProvider);
}
......// 其它四大组件和fragment接口省略
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) { // 6
this.main3ActivitySubcomponentBuilderProvider = new
Provider<ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent.Builder>() {
@Override
public ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent.Builder get() {
return new Main3ActivitySubcomponentBuilder(); // 7
}
};
}
@Override
public void inject(Main3Application arg0) { // 9.2
injectMain3Application(arg0);
}
private Main3Application injectMain3Application(Main3Application instance) {
DaggerApplication_MembersInjector.injectActivityInjector( // 9.3
instance, getDispatchingAndroidInjectorOfActivity());
......// 其它四大组件和fragment接口省略
return instance;
}
private static final class Builder extends AppComponent.Builder { // 2
private Main3Application seedInstance;
// 3 这里的调用是在 DaggerAppComponent.builder().create(this); 中实现的
@Override
public AppComponent build() {
if (seedInstance == null) {
throw new IllegalStateException(
Main3Application.class.getCanonicalName() + " must be set");
}
return new DaggerAppComponent(this); // 4 创建DaggerAppComponent对象
}
@Override
public void seedInstance(Main3Application arg0) {
this.seedInstance = Preconditions.checkNotNull(arg0);
}
}
// 8这里的使用工厂类来调用build方法(同3)
private final class Main3ActivitySubcomponentBuilder
extends ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent.Builder {
private Main3Activity seedInstance;
@Override
public ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent build() {
if (seedInstance == null) {
throw new IllegalStateException(Main3Activity.class.getCanonicalName() + " must be set");
}
return new Main3ActivitySubcomponentImpl(this); // 9
}
@Override
public void seedInstance(Main3Activity arg0) {
this.seedInstance = Preconditions.checkNotNull(arg0);
}
}
private final class Main3ActivitySubcomponentImpl
implements ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent { // 10
private Main3ActivitySubcomponentImpl(Main3ActivitySubcomponentBuilder builder) {}
@Override
public void inject(Main3Activity arg0) { // 11
injectMain3Activity(arg0);
}
private Main3Activity injectMain3Activity(Main3Activity instance) { // 12
Main3Activity_MembersInjector.injectMainPresenter(instance, new Main3Presenter());
return instance;
}
}
}
DaggerAppComponent 承担着依赖注入的多项重要工作,其执行步骤如下:
步骤1:builder() 方法:创建一个 Builder 对象,该对象继承自 AndroidInjector.Builder;
步骤2:内部类 Builder 继承自 AppComponent.Builder,而 AppComponent.Builder 继承自 AndroidInjector.Builder;
步骤3:回到 MainApplication,其中使用 DaggerAppComponent.builder().create(this) 创建 AndroidInjector<T>,这里的 create方法实际上使用的是 AndroidInjector 接口中 Builder 抽象类中的 create 方法,该方法依次调用了 seedInstance 和 build 两个方法来构建 AndroidInjector<T>,这两个方法最终由 DaggerAppComponent.Builder 类来实现,接着走 build 方法;
步骤4:build 方法中创建了一个 DaggerAppComponent 对象,参数为 DaggerAppComponent.Builder;
步骤5-7:DaggerAppComponent 的构造方法中调用 initialize(builder),initialize 中返回一个ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent.Builder的Provider 对象,这个 Builder 的具体实现交给了 Main3ActivitySubcomponentBuilder(多态);(详见 ActivityBindingModule_Main3ActivityInjector)
步骤8:Main3ActivitySubcomponentBuilder 继承自ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent.Builder,间接继承自AndroidInjector.Builder<Main3Activity>,因此还是会进入 Main3ActivitySubcomponentBuilder的build方法;
步骤9:build 方法返回一个 ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent(继承自AndroidInjector),具体的实现交给了它的实现类 Main3ActivitySubcomponentImpl 来完成;
步骤9.1:走到这里回头看看步骤4,在这里已经生成了 AndroidInjector<DaggerApplication> 即生成的 DaggerAppComponent 对象,紧接着就是使用这个生成的 AndroidInjector<DaggerApplication> 调用 inject 方法进行依赖注入;
1 2 3 | AndroidInjector<DaggerApplication> applicationInjector = (AndroidInjector<DaggerApplication>) applicationInjector(); applicationInjector.inject(this); |
步骤9.2:这里的 applicationInjector.inject(this); 实际上调用的是 DaggerAppComponent 的 inject 方法,进入injectMain3Application 方法,通过 DaggerApplication_MembersInjector 的 injectActivityInjector 进行注入;
步骤9.3:DaggerApplication_MembersInjector的injectActivityInjector 对 DaggerApplication 中的 DispatchingAndroidInjector<T>进行赋值(详见下面 DaggerApplication_MembersInjector 类),这里的参数 getDispatchingAndroidInjectorOfActivity 方法里得到的为真正的 DispatchingAndroidInjector;
步骤9.4:getDispatchingAndroidInjectorOfActivity 继续追踪得到的就是 main3ActivitySubcomponentBuilderProvider,其实现为Main3ActivitySubcomponentBuilder,这里由步骤9可知,真正的 DispatchingAndroidInjector 的实现又交给了 Main3ActivitySubcomponentImpl 实现类来完成。
步骤9.5:这里我们要注入的目标类是 Activity,而在 Activity 中我们使用 AndroidInjection.inject(this); 来实现依赖注入, AndroidInjection 的 inject 方法中会调用 DispatchingAndroidInjector<Activity> 来完成依赖注入(详见下面 AndroidInjection 类),而 DispatchingAndroidInjector 的是实现类是 Main3ActivitySubcomponentImpl,因此 Activity 实际的依赖注入工作又转移到了这里;
步骤10-12:最终 Main3Presenter 注入到 Activity 的工作交给了 Main3Activity_MembersInjector 的 injectMainPresenter 方法(详见下面的 Main3Activity_MembersInjector 类)。
ActivityBindingModule
ActivityBindingModule类中使用@ContributesAndroidInjector() 注解标注的类即为依赖注入的目标类,Dagger2会生成具体的注入类ActivityBindingModule_Main3ActivityInjector。
@Module
public abstract class ActivityBindingModule {
@ActivityScoped
@ContributesAndroidInjector()
abstract Main3Activity main3ActivityInjector();
}
ActivityBindingModule_Main3ActivityInjector
@Module(subcomponents = ActivityBindingModule_Main3ActivityInjector.Main3ActivitySubcomponent.class)
public abstract class ActivityBindingModule_Main3ActivityInjector {
private ActivityBindingModule_Main3ActivityInjector() {}
@Binds
@IntoMap
@ActivityKey(Main3Activity.class)
abstract AndroidInjector.Factory<? extends Activity> bindAndroidInjectorFactory(
Main3ActivitySubcomponent.Builder builder);
@Subcomponent
@ActivityScoped
public interface Main3ActivitySubcomponent extends AndroidInjector<Main3Activity> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<Main3Activity> {}
}
}
@Subcomponent:该注解,会生成XXXComponentBuilder的final类, 即上面的实现类Main3ActivitySubcomponentBuilder
DaggerApplication_MembersInjector
public final class DaggerApplication_MembersInjector implements MembersInjector<DaggerApplication> {
private final Provider<DispatchingAndroidInjector<Activity>> activityInjectorProvider;
……// 其它四大组件和fragment接口省略
public DaggerApplication_MembersInjector(
Provider<DispatchingAndroidInjector<Activity>> activityInjectorProvider,
……// 其它四大组件和fragment接口省略
) {
this.activityInjectorProvider = activityInjectorProvider;
……// 其它四大组件和fragment接口省略
}
public static MembersInjector<DaggerApplication> create(
Provider<DispatchingAndroidInjector<Activity>> activityInjectorProvider,
……// 其它四大组件和fragment接口省略) {
return new DaggerApplication_MembersInjector(
activityInjectorProvider,
……// 其它四大组件和fragment接口省略
);
}
@Override
public void injectMembers(DaggerApplication instance) {
injectActivityInjector(instance, activityInjectorProvider.get());
……// 其它四大组件和fragment接口省略
injectSetInjected(instance);
}
public static void injectActivityInjector(
DaggerApplication instance, DispatchingAndroidInjector<Activity> activityInjector) {
instance.activityInjector = activityInjector;
}
……// 其它四大组件和fragment接口省略
public static void injectSetInjected(DaggerApplication instance) {
instance.setInjected();
}
}
通过这个类为四大组件和Fragment设置依赖注入分发器DispatchingAndroidInjector<T>,在上面的injectActivityInjector方法中为DaggerApplication中的DispatchingAndroidInjector<T>进行设置。
AndroidInjection
public final class AndroidInjection {
public static void inject(Activity activity) {
checkNotNull(activity, "activity");
Application application = activity.getApplication();
if (!(application instanceof HasActivityInjector)) {
throw new RuntimeException(
String.format(
"%s does not implement %s",
application.getClass().getCanonicalName(),
HasActivityInjector.class.getCanonicalName()));
}
AndroidInjector<Activity> activityInjector = ((HasActivityInjector) application).activityInjector();
checkNotNull(activityInjector, "%s.activityInjector() returned null", application.getClass());
activityInjector.inject(activity);
}
……// 其它四大组件和fragment接口省略
private AndroidInjection() {}
}
这里调用Application的activityInjector方法中的DispatchingAndroidInjector<Activity> 依赖注入分发器进行依赖注入。
Main3Activity_MembersInjector
public final class Main3Activity_MembersInjector implements MembersInjector<Main3Activity> {
private final Provider<Main3Presenter> mainPresenterProvider;
public Main3Activity_MembersInjector(Provider<Main3Presenter> mainPresenterProvider) {
this.mainPresenterProvider = mainPresenterProvider;
}
public static MembersInjector<Main3Activity> create(Provider<Main3Presenter> mainPresenterProvider) {
return new Main3Activity_MembersInjector(mainPresenterProvider);
}
@Override
public void injectMembers(Main3Activity instance) {
injectMainPresenter(instance, mainPresenterProvider.get());
}
public static void injectMainPresenter(Main3Activity instance, Main3Presenter mainPresenter) {
instance.mainPresenter = mainPresenter;
}
}
将mainPresenterProvider中创建好的MainPresenter实例赋值给instance(即MainActivity)的成员mainPresenter,这样用@Inject标注的mainPresenter就得到了实例化。