Android主流三方库源码分析:Dagger2(1)

public class WanAndroidApp extends Application implements HasActivityInjector {

// 3

@Inject

DispatchingAndroidInjector mAndroidInjector;

private static volatile AppComponent appComponent;

@Override

public void onCreate() {

super.onCreate();

// 1

appComponent = DaggerAppComponent.builder()

.build();

// 2

appComponent.inject(this);

}

// 4

@Override

public AndroidInjector activityInjector() {

return mAndroidInjector;

}

}

复制代码

首先,在注释1处,使用AppModule模块和httpModule模块构建出AppComponent的实现类DaggerAppComponent。这里看一下AppComponent的配置代码:

@Singleton

@Component(modules = {AndroidInjectionModule.class,

AndroidSupportInjectionModule.class,

AbstractAllActivityModule.class,

AbstractAllFragmentModule.class,

AbstractAllDialogFragmentModule.class}

)

public interface AppComponent {

/**

  • 注入WanAndroidApp实例

  • @param wanAndroidApp WanAndroidApp

*/

void inject(WanAndroidApp wanAndroidApp);

}

复制代码

可以看到,AppComponent依赖了AndroidInjectionModule模块,它包含了一些基础配置的绑定设置,如activityInjectorFactories、fragmentInjectorFactories等等,而AndroidSupportInjectionModule模块显然就是多了一个supportFragmentInjectorFactories的绑定设置,activityInjectorFactories的内容如所示:

@Beta

@Module

public abstract class AndroidInjectionModule {

@Multibinds

abstract Map<Class<? extends Activity>, AndroidInjector.Factory<? extends Activity>>

activityInjectorFactories();

@Multibinds

abstract Map<Class<? extends Fragment>, AndroidInjector.Factory<? extends Fragment>>

fragmentInjectorFactories();

}

复制代码

接着,下面依赖的AbstractAllActivityModule、 AbstractAllFragmentModule、AbstractAllDialogFragmentModule则是为项目的所有Activity、Fragment、DialogFragment提供的统一基类抽象Module,这里看下AbstractAllActivityModule的配置:

@Module(subcomponents = {BaseActivityComponent.class})

public abstract class AbstractAllActivityModule {

@ContributesAndroidInjector(modules = MainActivityModule.class)

abstract MainActivity contributesMainActivityInjector();

@ContributesAndroidInjector(modules = SplashActivityModule.class)

abstract SplashActivity contributesSplashActivityInjector();

}

复制代码

可以看到,项目下的所有xxxActiviity都有对应的contributesxxxActivityInjector()方法提供实例注入。并且,注意到AbstractAllActivityModule这个模块依赖的 subcomponents为BaseActivityComponent,前面说过了,每一个继承于BaseActivity的Activity都继承于BaseActivityComponent这一个subcomponents。同理,AbstractAllFragmentModule与AbstractAllDialogFragmentModule也是类似的实现模式,如下所示:

// 1

@Module(c = BaseFragmentComponent.class)

public abstract class AbstractAllFragmentModule {

@ContributesAndroidInjector(modules = CollectFragmentModule.class)

abstract CollectFragment contributesCollectFragmentInject();

@ContributesAndroidInjector(modules = KnowledgeFragmentModule.class)

abstract KnowledgeHierarchyFragment contributesKnowledgeHierarchyFragmentInject();

}

// 2

@Module(subcomponents = BaseDialogFragmentComponent.class)

public abstract class AbstractAllDialogFragmentModule {

@ContributesAndroidInjector(modules = SearchDialogFragmentModule.class)

abstract SearchDialogFragment contributesSearchDialogFragmentInject();

@ContributesAndroidInjector(modules = UsageDialogFragmentModule.class)

abstract UsageDialogFragment contributesUsageDialogFragmentInject();

}

复制代码

注意到注释1和注释2处的代码,AbstractAllFragmentModule和AbstractAllDialogFragmentModule的subcomponents为BaseFragmentComponent、BaseDialogFragmentComponent,很显然,同AbstractAllActivityModule的子组件BaseActivityComponent一样,它们都是作为一个通用的子组件。

然后,回到我们配置项目下的Application下面的注释2处的代码,在这里使用了第一步Dagger为我们构建的DaggerAppComponent对象将当期的Application实例注入了进去,交给了Dagger这个依赖大管家去管理。最终,Dagger2内部创建的mAndroidInjector对象会在注释3处的地方进行实例赋值。在注释4处,实现HasActivityInjector接口,重写activityInjector()方法,将我们上面得到的mAndroidInjector对象返回。这里的mAndroidInjector是一个类型为DispatchingAndroidInjector的对象,可以这样理解它:它能够执行Android框架下的核心成员如Activity、Fragment的成员注入,在我们项目下的Application中将DispatchingAndroidInjector的泛型指定为Activity就说明它承担起了所有Activity成员依赖的注入。那么,如何指定某一个Activity能被纳入DispatchingAndroidInjector这个所有Activity的依赖总管的口袋中呢?接着看使用步骤4。

4、最后,将目标Activity纳入Activity依赖分配总管DispatchingAndroidInjector的囊中。


很简单,只需在目标Activity的onCreate()方法前的super.onCreate(savedInstanceState)前配置一行代码 AndroidInjection.inject(this),如下所示:

public abstract class BaseActivity extends AbstractSimpleActivity implements

AbstractView {

@Inject

protected T mPresenter;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

AndroidInjection.inject(this);

super.onCreate(savedInstanceState);

}

}

复制代码

这里使用了@Inject表明了需要注入mPresenter实例,然后,我们需要在具体的Presenter类的构造方法上使用@Inject提供基于当前构造方法的mPresenter实例,如下所示:

public class MainPresenter extends BasePresenter<MainContract.View> implements MainContract.Presenter {

@Inject

MainPresenter(DataManager dataManager) {

super(dataManager);

this.mDataManager = dataManager;

}

}

复制代码

从上面的使用流程中,有三个关键的核心实现是我们需要了解的,如下所示:

  • 1、appComponent = DaggerAppComponent.builder().build()这句代码如何构建出DaggerAPPComponent的?

  • 2、appComponent.inject(this)是如何将mAndroidInjector实例赋值给当前的Application的?

  • 3、在目标Activity下的AndroidInjection.inject(this)这句代码是如何将当前Activity对象纳入依赖分配总管DispatchingAndroidInjector囊中的呢?

下面,让我们来逐个一一地来探索其中的奥妙吧~

三、DaggerAppComponent.builder().build()是如何构建出DaggerAPPComponent的?

================================================================================================================================

首先,我们看到DaggerAppComponent的builder()方法:

public static Builder builder() {

return new Builder();

}

复制代码

里面直接返回了一个新建的Builder静态内部类对象,看看它的构造方法中做了什么:

public static final class Builder {

private Builder() {}

}

复制代码

看来,Builder的默认构造方法什么也没有做,那么,真正的实现肯定在Builder对象的build()方法中,接着看到build()方法。

public static final class Builder {

public AppComponent build() {

return new DaggerAppComponent(this);

}

}

复制代码

在Builder的build()方法中直接返回了新建的DaggerAppComponent对象。下面,看看DaggerAppComponent的构造方法:

private DaggerAppComponent(Builder builder) {

initialize(builder);

}

复制代码

在DaggerAppComponent的构造方法中调用了initialize方法,顾名思义,它就是真正初始化项目全局依赖配置的地方了,下面,来看看它内部的实现:

private void initialize(final Builder builder) {

// 1

this.mainActivitySubcomponentBuilderProvider =

new Provider<

AbstractAllActivityModule_ContributesMainActivityInjector.MainActivitySubcomponent

.Builder>() {

@Override

public AbstractAllActivityModule_ContributesMainActivityInjector.MainActivitySubcomponent

.Builder

get() {

// 2

return new MainActivitySubcomponentBuilder();

}

};

// 一系列xxxActivitySubcomponentBuilderProvider的创建赋值代码块

}

复制代码

在注释1处,新建了一个mainActivit的子组件构造器实例提供者Provider。在注释2处,使用匿名内部类的方式重写了该Provider的get()方法,返回一个新创建好的MainActivitySubcomponentBuilder对象。很显然,它就是负责创建管理MAinActivity中所需依赖的Subcomponent建造者。接下来我们重点来分析下MainActivitySubcomponentBuilder这个类的作用。

// 1

private final class MainActivitySubcomponentBuilder

extends AbstractAllActivityModule_ContributesMainActivityInjector.MainActivitySubcomponent

.Builder {

private MainActivity seedInstance;

@Override

public AbstractAllActivityModule_ContributesMainActivityInjector.MainActivitySubcomponent

build() {

if (seedInstance == null) {

throw new IllegalStateException(MainActivity.class.getCanonicalName() + " must be set");

}

// 2

return new MainActivitySubcomponentImpl(this);

}

@Override

public void seedInstance(MainActivity arg0) {

// 3

this.seedInstance = Preconditions.checkNotNull(arg0);

}

}

复制代码

首先,在注释1处,MainActivitySubcomponentBuilder继承了AbstractAllActivityModule_ContributesMainActivityInjector内部的子组件MainActivitySubcomponent的内部的子组件建造者类Builder,如下所示:

@Subcomponent(modules = MainActivityModule.class)

public interface MainActivitySubcomponent extends AndroidInjector {

@Subcomponent.Builder

abstract class Builder extends

AndroidInjector.Builder {}

}

复制代码

可以看到,这个子组件建造者Builder又继承了AndroidInjector的抽象内部类Builder,那么,这个AndroidInjector到底是什么呢?

顾名思义,AndroidInjector是一个Android注射器,它为每一个具体的子类型,即核心Android类型Activity和Fragment执行成员注入。

接下来我们便来分析下AndroidInjector的内部实现,源码如下所示:

public interface AndroidInjector {

void inject(T instance);

// 1

interface Factory {

AndroidInjector create(T instance);

}

// 2

abstract class Builder implements AndroidInjector.Factory {

@Override

public final AndroidInjector create(T instance) {

seedInstance(instance);

return build();

}

@BindsInstance

public abstract void seedInstance(T instance);

public abstract AndroidInjector build();

}

}

复制代码

在注释1处,使用了抽象工厂模式,用来创建一个具体的Activity或Fragment类型的AndroidInjector实例。注释2处,Builder实现了AndroidInjector.Factory,它是一种Subcomponent.Builder的通用实现模式,在重写的create()方法中,进行了实例保存seedInstance()和具体Android核心类型的构建。

接着,我们回到MainActivitySubcomponentBuilder类,可以看到,它实现了AndroidInjector.Builder的seedInstance()和build()方法。在注释3处首先播种了MainActivity的实例,然后 在注释2处新建了一个MainActivitySubcomponentImpl对象返回。我们看看MainActivitySubcomponentImpl这个类是如何将mPresenter依赖注入的,相关源码如下:

private final class MainActivitySubcomponentImpl

implements AbstractAllActivityModule_ContributesMainActivityInjector

.MainActivitySubcomponent {

private MainPresenter getMainPresenter() {

// 2

return MainPresenter_Factory.newMainPresenter(

DaggerAppComponent.this.provideDataManagerProvider.get());

}

@Override

public void inject(MainActivity arg0) {

// 1

injectMainActivity(arg0);

}

private MainActivity injectMainActivity(MainActivity instance) {

// 3

BaseActivity_MembersInjector

.injectMPresenter(instance, getMainPresenter());

return instance;

}

复制代码

在注释1处,MainActivitySubcomponentImpl实现了AndroidInjector接口的inject()方法,在injectMainActivity()首先调用getMainPresenter()方法从MainPresenter_Factory工厂类中新建了一个MainPresenter对象。我们看看MainPresenter的newMainPresenter()方法:

public static MainPresenter newMainPresenter(DataManager dataManager) {

return new MainPresenter(dataManager);

}

复制代码

这里直接新建了一个MainPresenter。然后我们回到MainActivitySubcomponentImpl类的注释3处,继续调用了BaseActivity_MembersInjector的injectMPresenter()方法,顾名思义,可以猜到,它是BaseActivity的成员注射器,继续看看injectMPresenter()内部:

public static void injectMPresenter(

BaseActivity instance, T mPresenter) {

instance.mPresenter = mPresenter;

}

复制代码

可以看到,这里直接将需要的mPresenter实例赋值给了BaseActivity的mPresenter,当然,这里其实是指的BaseActivity的子类MainActivity,其它的xxxActivity的依赖管理机制都是如此。

四、appComponent.inject(this)是如何将mAndroidInjector实例赋值给当前的Application的?

====================================================================================================================================

我们继续查看appComponent的inject()方法:

@Override

public void inject(WanAndroidApp wanAndroidApp) {

injectWanAndroidApp(wanAndroidApp);

}

复制代码

在inject()方法里调用了injectWanAndroidApp(),继续查看injectWanAndroidApp()方法:

private WanAndroidApp injectWanAndroidApp(WanAndroidApp instance) {

WanAndroidApp_MembersInjector.injectMAndroidInjector(

instance,

getDispatchingAndroidInjectorOfActivity());

return instance;

}

复制代码

首先,执行getDispatchingAndroidInjectorOfActivity()方法得到了一个Activity类型的DispatchingAndroidInjector对象,继续查看getDispatchingAndroidInjectorOfActivity()方法:

private DispatchingAndroidInjector getDispatchingAndroidInjectorOfActivity() {

return DispatchingAndroidInjector_Factory.newDispatchingAndroidInjector(

getMapOfClassOfAndProviderOfFactoryOf());

}

复制代码

在getDispatchingAndroidInjectorOfActivity()方法里面,首先调用了getMapOfClassOfAndProviderOfFactoryOf()方法,我们看到这个方法:

private Map<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>>

getMapOfClassOfAndProviderOfFactoryOf() {

return MapBuilder

.<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>>

newMapBuilder(8)

.put(MainActivity.class, (Provider) mainActivitySubcomponentBuilderProvider)

.put(SplashActivity.class, (Provider) splashActivitySubcomponentBuilderProvider)

.put(ArticleDetailActivity.class,

(Provider) articleDetailActivitySubcomponentBuilderProvider)

.put(KnowledgeHierarchyDetailActivity.class,

(Provider) knowledgeHierarchyDetailActivitySubcomponentBuilderProvider)

.put(LoginActivity.class, (Provider) loginActivitySubcomponentBuilderProvider)

.put(RegisterActivity.class, (Provider) registerActivitySubcomponentBuilderProvider)

.put(AboutUsActivity.class, (Provider) aboutUsActivitySubcomponentBuilderProvider)

.put(SearchListAct外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

资料获取→专栏
ivity.class, (Provider) searchListActivitySubcomponentBuilderProvider)

.build();

}

复制代码

可以看到,这里新建了一个建造者模式实现的MapBuilder,并且同时制定了固定容量为8,将项目下使用了AndroidInjection.inject(mActivity)方法的8个Activity对应的xxxActivitySubcomponentBuilderProvider保存起来。

我们再回到getDispatchingAndroidInjectorOfActivity()方法,这里将上面得到的Map容器传入了DispatchingAndroidInjector_Factory的newDispatchingAndroidInjector()方法中,这里应该就是新建DispatchingAndroidInjector的地方了。我们点进去看看:

public static DispatchingAndroidInjector newDispatchingAndroidInjector(

Map<Class<? extends T>, Provider<AndroidInjector.Factory<? extends T>>> injectorFactories) {

return new DispatchingAndroidInjector(injectorFactories);

}

复制代码

在这里,果然新建了一个DispatchingAndroidInjector对象。继续看看DispatchingAndroidInjector的构造方法:

@Inject

DispatchingAndroidInjector(

Map<Class<? extends T>, Provider<AndroidInjector.Factory<? extends T>>> injectorFactories) {

this.injectorFactories = injectorFactories;

}

复制代码

这里仅仅是将传进来的Map容器保存起来了。

我们再回到WanAndroidApp_MembersInjector的injectMAndroidInjector()方法,将上面得到的DispatchingAndroidInjector实例传入,继续查看injectMAndroidInjector()这个方法:

public static void injectMAndroidInjector(

WanAndroidApp instance, DispatchingAndroidInjector mAndroidInjector) {

instance.mAndroidInjector = mAndroidInjector;

}

复制代码

可以看到,最后在WanAndroidApp_MembersInjector的injectMAndroidInjector()方法中,直接将新建好的DispatchingAndroidInjector实例赋值给了WanAndroidApp的mAndroidInjector。

五、在目标Activity下的AndroidInjection.inject(this)这句代码是如何将当前Activity对象纳入依赖分配总管DispatchingAndroidInjector囊中的呢?

=======================================================================================================================================================================

首先,我们看到AndroidInjection.inject(this)这个方法:

public static void inject(Activity activity) {

checkNotNull(activity, “activity”);

// 1

Application application = activity.getApplication();

if (!(application instanceof HasActivityInjector)) {

throw new RuntimeException(

String.format(

“%s does not implement %s”,

application.getClass().getCanonicalName(),

HasActivityInjector.class.getCanonicalName()));

}

// 2

AndroidInjector activityInjector =

((HasActivityInjector) application).activityInjector();

checkNotNull(activityInjector, “%s.activityInjector() returned null”, application.getClass());

// 3

activityInjector.inject(activity);

复制代码

}

在注释1处,会先判断当前的application是否实现了HasActivityInjector这个接口,如果没有,则抛出RuntimeException。如果有,会继续在注释2处调用application的activityInjector()方法得到DispatchingAndro
idInjector实例。最后,在注释3处,会将当前的activity实例传入activityInjector的inject()方法中。我们继续查看inject()方法:

@Override

public void inject(T instance) {

boolean wasInjected = maybeInject(instance);

if (!wasInjected) {

throw new IllegalArgumentException(errorMessageSuggestions(instance));

}

}

复制代码

DispatchingAndroidInjector的inject()方法,它的作用就是给传入的instance实例执行成员注入。具体在这个案例中,其实就是负责将创建好的Presenter实例赋值给BaseActivity对象 的mPresenter全局变量。在inject()方法中,又调用了maybeInject()方法,我们继续查看它:

@CanIgnoreReturnValue

public boolean maybeInject(T instance) {

// 1

Provider<AndroidInjector.Factory<? extends T>> factoryProvider =

injectorFactories.get(instance.getClass());

if (factoryProvider == null) {

return false;

}

@SuppressWarnings(“unchecked”)

// 2

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

try {

// 3

AndroidInjector injector =

checkNotNull(

factory.create(instance), “%s.create(I) should not return null.”, factory.getClass());

// 4

injector.inject(instance);

return true;

} catch (ClassCastException e) {

}

}

复制代码

在注释1处,我们从injectorFactories(前面得到的Map容器)中根据当前Activity实例拿到了factoryProvider对象,这里我们具体一点,看到MainActivity对应的factoryProvider,也就是我们研究的第一个问题中的mainActivitySubcomponentBuilderProvider:

private void initialize(final Builder builder) {

this.mainActivitySubcomponentBuilderProvider =

new Provider<

AbstractAllActivityModule_ContributesMainActivityInjector.MainActivitySubcomponent

.Builder>() {

@Override

public AbstractAllActivityModule_ContributesMainActivityInjector.MainActivitySubcomponent

.Builder

get() {

return new MainActivitySubcomponentBuilder();

}

};

}

复制代码

在maybeInject()方法的注释2处,调用了mainActivitySubcomponentBuilderProvider的get()方法得到了一个新建的MainActivitySubcomponentBuilder对象。在注释3处执行了它的create方法,create()方法的具体实现在AndroidInjector的内部类Builder中:

abstract class Builder implements AndroidInjector.Factory {

@Override

public final AndroidInjector create(T instance) {

seedInstance(instance);

return build();

}

复制代码

看到这里,我相信看过第一个问题的同学已经明白后面是怎么回事了。在create()方法中,我们首先MainActivitySubcomponentBuilder的seedInstance()将MainActivity实例注入,然后再调用它的build()方法新建了一个MainActivitySubcomponentImpl实例返回。

最后,在注释4处,执行了MainActivitySubcomponentImpl的inject()方法:

oryProvider对象,这里我们具体一点,看到MainActivity对应的factoryProvider,也就是我们研究的第一个问题中的mainActivitySubcomponentBuilderProvider:

private void initialize(final Builder builder) {

this.mainActivitySubcomponentBuilderProvider =

new Provider<

AbstractAllActivityModule_ContributesMainActivityInjector.MainActivitySubcomponent

.Builder>() {

@Override

public AbstractAllActivityModule_ContributesMainActivityInjector.MainActivitySubcomponent

.Builder

get() {

return new MainActivitySubcomponentBuilder();

}

};

}

复制代码

在maybeInject()方法的注释2处,调用了mainActivitySubcomponentBuilderProvider的get()方法得到了一个新建的MainActivitySubcomponentBuilder对象。在注释3处执行了它的create方法,create()方法的具体实现在AndroidInjector的内部类Builder中:

abstract class Builder implements AndroidInjector.Factory {

@Override

public final AndroidInjector create(T instance) {

seedInstance(instance);

return build();

}

复制代码

看到这里,我相信看过第一个问题的同学已经明白后面是怎么回事了。在create()方法中,我们首先MainActivitySubcomponentBuilder的seedInstance()将MainActivity实例注入,然后再调用它的build()方法新建了一个MainActivitySubcomponentImpl实例返回。

最后,在注释4处,执行了MainActivitySubcomponentImpl的inject()方法:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值