android dagger2 讲解,告别Dagger2模板代码:DaggerAndroid原理解析

本文深入剖析Dagger-Android如何通过Dagger2实现依赖注入,重点分析Application中的关键代码及Activity的注入原理。通过创建、初始化组件,构建依赖注入的管理器,最终实现通过AndroidInjection.inject(this)一行代码即可完成Activity的依赖注入。
摘要由CSDN通过智能技术生成

本系列所有文章:

概述

距离我的上一篇文章发布以来,有幸收获了一些朋友的认可,我很开心。

在上一篇文章中,我简单叙述了Dagger2这个库目前在Android开发中的一些短板,为什么我们学习Dagger-Android这个拓展库,以及如何使用这个拓展库。

今天我们进行代码分析,看看Dagger-Android是如何基于Dagger2实现一行代码实现所有同类组件依赖注入的。

阅读本文也许您需要准备的

本文可能需要您对Dagger2有一定的了解,包括它内部模板代码生成的一些逻辑。

核心代码

书承上文,我们知道,我们实现依赖注入的代码主要为以下两行:

public class MyApplication extends Application implements HasActivityInjector {

@Inject

DispatchingAndroidInjector dispatchingAndroidInjector;

@Override

public void onCreate() {

super.onCreate();

//1.Application级的依赖注入

DaggerMyAppComponent.create().inject(this);

}

@Override

public AndroidInjector activityInjector() {

return dispatchingAndroidInjector;

}

}

public class BaseActivity extends AppCompatActivity{

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

//2.Activity级的依赖注入

AndroidInjection.inject(this);

super.onCreate(savedInstanceState);

}

}

抛开这两行,也许我们还有更多疑问:

1.MyApplication中的dispatchingAndroidInjector成员是干嘛的

2.MyApplication实现的HasActivityInjector接口和实现的activityInjector()方法又是干嘛的

3.为什么这样2行依赖注入代码,就能代替之前我们每个Activity都需要写的模板代码呢:

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// DO THIS FIRST. Otherwise frombulator might be null!

((SomeApplicationBaseType) getContext().getApplicationContext())

.getApplicationComponent()

.newActivityComponentBuilder()

.activity(this)

.build()

.inject(this);

// ... now you can write the exciting code

}

直接公布结论:

d4d62945d9c8

这里写图片描述

d4d62945d9c8

这里写图片描述

d4d62945d9c8

这三张图描述了很多东西,我们不需要先去看懂它,我们会随着我们的步骤,一步步分析透彻它,拨开云雾见晴天。、

首先我们分析Application中的这行代码:

DaggerMyAppComponent.create().inject(this);

一、DaggerMyAppComponent.create()原理

我们先点开create()方法,可以看到,无非是初始化了一个DaggerMyAppComponent对象,然后执行了initialize()方法

public static MyAppComponent create() {

return new Builder().build();

}

public static final class Builder {

private Builder() {

}

public MyAppComponent build() {

return new DaggerMyAppComponent(this);

}

}

private DaggerMyAppComponent(Builder builder) {

assert builder != null;

initialize(builder);

}

我们接着看initialize()方法:

private void initialize(final Builder builder) {

//1

this.mainActivitySubcomponentBuilderProvider =

new dagger.internal.Factory<

AllActivitysModule_ContributeMainActivitytInjector.MainActivitySubcomponent.Builder>() {

@Override

public AllActivitysModule_ContributeMainActivitytInjector.MainActivitySubcomponent.Builder

get() {

return new MainActivitySubcomponentBuilder();

}

};

this.bindAndroidInjectorFactoryProvider = (Provider) mainActivitySubcomponentBuilderProvider;

this.secondActivitySubcomponentBuilderProvider =

new dagger.internal.Factory<

AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent

.Builder>() {

@Override

public AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent

.Builder

get() {

return new SecondActivitySubcomponentBuilder();

}

};

this.bindAndroidInjectorFactoryProvider2 = (Provider) secondActivitySubcomponentBuilderProvider;

//2

this.mapOfClassOfAndProviderOfFactoryOfProvider =

MapProviderFactory

., AndroidInjector.Factory extends Activity>>builder(2)

.put(MainActivity.class, bindAndroidInjectorFactoryProvider)

.put(SecondActivity.class, bindAndroidInjectorFactoryProvider2)

.build();

//3

this.dispatchingAndroidInjectorProvider =

DispatchingAndroidInjector_Factory.create(mapOfClassOfAndProviderOfFactoryOfProvider);

//4

this.myApplicationMembersInjector =

MyApplication_MembersInjector.create(dispatchingAndroidInjectorProvider);

}

这就有点难受了,代码很多,我们一步步慢慢分析。

我们不要一次想着把这些代码彻底读懂,我们首先大概对整个流程有个了解,之后慢慢拆分代码不迟:

我们可以理解为直接初始化了MainActivitySubcomponentBuilder和SecondActivitySubcomponentBuilder的对象,这个对象能够提供一个对应ActivityComponent的实例化对象,有了这个实例化对象,我们就能够对对应的Activity进行依赖注入。

这个很明显了,把所有ActivityComponent的实例化对象都存储到一个Map中,然后这个Map通过放入mapOfClassOfAndProviderOfFactoryOfProvider对象中。

通过mapOfClassOfAndProviderOfFactoryOfProvider初始化dispatchingAndroidInjectorProvider对象

通过dispatchingAndroidInjectorProvider对象初始化myApplicationMembersInjector对象

好的基本差不多了 我们看看每个步骤都是如何实现的

第1步详细分析

以SecondActivity的这行代码为例:

this.secondActivitySubcomponentBuilderProvider =

new dagger.internal.Factory< //1.看这行,实际上是new了一个能提供SecondActivitySubcomponentBuilder()的Provider

AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent

.Builder>() {

@Override

public AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent

.Builder

get() {

//2.这个SecondActivitySubcomponentBuilder能干什么呢

return new SecondActivitySubcomponentBuilder();

}

};

private final class SecondActivitySubcomponentImpl

implements AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent {

private MembersInjector secondActivityMembersInjector;

//3.我们点开构造方法,看到实际是走了initialize(builder);

private SecondActivitySubcomponentImpl(SecondActivitySubcomponentBuilder builder) {

assert builder != null;

initialize(builder);

}

@SuppressWarnings("unchecked")

private void initialize(final SecondActivitySubcomponentBuilder builder) {

//4.实际上是初始化了一个SecondActivity_MembersInjector,这个Injector能够对SecondActivity所需要的对象提供注入

this.secondActivityMembersInjector =

SecondActivity_MembersInjector.create(SecondActivityModule_ProvideNameFactory.create());

}

@Override

public void inject(SecondActivity arg0) {

//5.我们不难想象,不久后当SecondActivity需要依赖注入,一定会执行这行代码进行对象注入

secondActivityMembersInjector.injectMembers(arg0);

}

}

看到这里我们明白了,实际上第一步是ApplicationComponent实例化了所有的ActivityComponent(就是那个能提供SecondActivitySubcomponentBuilder()的Provider)

然后每个ActivityComponent都能提供某个Activity依赖注入所需要的ActivityMembersInjector。

第2步第3步分析

第2步就很简单了,这些ActivityComponent都被放入了一个Map集合中,该集合又放入了apOfClassOfAndProviderOfFactoryOfProvider中,这个Provider实际上也是一个工厂,负责提供该Map的实例化

第3步也很好理解,我们MapProvider工厂交给了就是dispatchingAndroidInjectorProvider去管理。

第4步分析:

实际上我们传入dispatchingAndroidInjectorProvider做了什么呢?

我们看看MyApplication_MembersInjector对象是干嘛的:

//核心代码

public final class MyApplication_MembersInjector implements MembersInjector {

private final Provider> dispatchingAndroidInjectorProvider;

...

...

...

//依赖注入Application!

@Override

public void injectMembers(MyApplication instance) {

instance.dispatchingAndroidInjector = dispatchingAndroidInjectorProvider.get();

}

}

大家可以明白了,原来第四步初始化该对象时,会将传入的dispatchingAndroidInjectorProvider存储起来,将来用到的时候将其对象注入到需要注入的Application中:

public class MyApplication extends Application implements HasActivityInjector {

//就是注入给这个成员变量!

@Inject

DispatchingAndroidInjector dispatchingAndroidInjector;

//省略其他代码

...

...

}

整理思路

现在我们再来看一下这张图,相信您已经对这张图有所领会了。

d4d62945d9c8

这里写图片描述

可以看到,Application进行初始化时,仅仅一部DaggerMyAppComponent.create(),就已经处理了如此多的事件,初始化了这么多工厂类,等待我们去调用他们实现依赖注入了。

二、DaggerMyAppComponent.create().inject(this)原理

其实这个步骤就是确定一下我们上面的对Dagger-Android这个库的分析是否是对的,我们来看这行代码

public final class DaggerMyAppComponent implements MyAppComponent {

...

...

...

@Override

public void inject(MyApplication application) {

myApplicationMembersInjector.injectMembers(application);

}

}

这就和我们上面第四步的分析吻合了:

//我们刚才分析过的,再看一遍

//核心代码

public final class MyApplication_MembersInjector implements MembersInjector {

private final Provider> dispatchingAndroidInjectorProvider;

...

...

...

//依赖注入Application!

@Override

public void injectMembers(MyApplication instance) {

instance.dispatchingAndroidInjector = dispatchingAndroidInjectorProvider.get();

}

}

public class MyApplication extends Application implements HasActivityInjector {

//就是注入给这个成员变量!

@Inject

DispatchingAndroidInjector dispatchingAndroidInjector;

//省略其他代码

...

...

}

整理思路

d4d62945d9c8

这里写图片描述

可以看到,这一步实际上我们做了至关重要的一步,就是把Application中的这个不知道是干什么的成员变量进行了初始化!!!

@Inject

DispatchingAndroidInjector dispatchingAndroidInjector;

我们现在知道,这个dispatchingAndroidInjector中,实际拥有一个Map,Map中有着所有Activity所需依赖注入使用的Component!

可以说,这个看起来平凡无奇的成员变量,才是我们整个项目依赖注入的大管家!

顿悟

相信如果您认真一步步看到这里,对于下面的2个问题,您已经有了自己的答案:

1.MyApplication中的dispatchingAndroidInjector成员是干嘛的

三、 AndroidInjection.inject(this)原理

我们在初始化一个Activity,必然会调用BaseActivity中的这行代码:

AndroidInjection.inject(this)

我们好奇,为什么仅仅在BaseActivity这样1行依赖注入代码,就能代替之前我们每个Activity都需要写的模板代码呢?

答案近在眼前。

public final class AndroidInjection {

...

...

...

public static void inject(Activity activity) {

//核心代码如下

//1.获取Application

Application application = activity.getApplication();

//2.通过activityInjector()获取dispatchingAndroidInjector对象!

AndroidInjector activityInjector =

((HasActivityInjector) application).activityInjector();

//3.dispatchingAndroidInjector依赖注入

activityInjector.inject(activity);

}

}

前两步毫无技术含量,我们继续看activityInjector.inject(activity):

我们需要找到真正的activityInjector对象,就是DispatchingAndroidInjector:

public final class DispatchingAndroidInjector implements AndroidInjector {

@Override

public void inject(T instance) { //instance在这里为Activity

//1.执行maybeInject()方法

boolean wasInjected = maybeInject(instance);

}

public boolean maybeInject(T instance) { //instance在这里为Activity

//2.获取对应Provider

Provider> factoryProvider =

injectorFactories.get(instance.getClass());

AndroidInjector.Factory factory = (AndroidInjector.Factory) factoryProvider.get();

//3.获取对应的ActivityMembersInjector

AndroidInjector injector =

factory.getClass().getCanonicalName());

//4.注入到对应的Activity中

injector.inject(instance);

}

}

整理思路

d4d62945d9c8

可以看到,这一步实际上我们只是取得Application中的大管家dispatchingAndroidInjector,通过它取得了对应Activity的Inject实例,并进行依赖注入。

顿悟

相信如果您认真一步步看到这里,对于下面的2个问题,您已经有了自己的答案:

2.MyApplication实现的HasActivityInjector接口和实现的activityInjector()方法又是干嘛的

3.为什么这样2行依赖注入代码,就能代替之前我们每个Activity都需要写的模板代码呢:

至此,AndroidInject原理分析基本也到了尾声

附录

最后提供一下本文demo源码连接和图片资源,都已放到Github:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值