您现在的位置是:首页 >技术交流 >Android主流三方库源码分析:Dagger2网站首页技术交流
Android主流三方库源码分析:Dagger2
这里必须要注解成@Subcomponent.Builder表示是顶级@Subcomponent的内部类。AndroidInjector.Builder的泛型指定了BaseActivity,即表示每一个继承于BaseActivity的Activity都继承于同一个子组件(BaseActivityComponent)。
[]( )2、然后,创建一个将会导入Subcomponent的公有Module。
---------------------------------------------------------------------------------------------------
// 1
@Module(subcomponents = {BaseActivityComponent.class})
public abstract class AbstractAllActivityModule {
@ContributesAndroidInjector(modules = MainActivityModule.class)
abstract MainActivity contributesMainActivityInjector();
@ContributesAndroidInjector(modules = SplashActivityModule.class)
abstract SplashActivity contributesSplashActivityInjector();
// 一系列的对应Activity的contributesxxxActivityInjector
...
}
复制代码
在注释1处用subcomponents来表示开放全部依赖给AbstractAllActivityModule,使用Subcomponent的重要原因是它将应用的不同部分封装起来了。**@AppComponent负责维护共享的数据和对象,而不同处则由各自的@Subcomponent维护**。
[]( )3、接着,配置项目的Application。
--------------------------------------------------------------------------------------
public class WanAndroidApp extends Application implements HasActivityInjector {
// 3
@Inject
DispatchingAndroidInjector<Activity> 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<Activity> 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<MainActivity> {}
}
复制代码
可以看到,这个子组件建造者Builder又继承了AndroidInjector的抽象内部类Builder,那么,这个AndroidInjector到底是什么呢?
顾名思义,**AndroidInjector**是一个Android注射器,它**为每一个具体的子类型,即核心Android类型Activity和Fragment执行成员注入。**
接下来我们便来分析下AndroidInjector的内部实现,源码如下所示:
public interface AndroidInjector {
void inject(T instance);
// 1
interface Factory<T> {
AndroidInjector<T> create(T instance);
}
// 2
abstract class Builder<T> implements AndroidInjector.Factory<T> {
@Override
public final AndroidInjector<T> create(T instance) {
seedInstance(instance);
return build();
}
@BindsInstance
public abstract void seedInstance(T instance);
public abstract AndroidInjector<T> 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(SearchListActivity.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<T>(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<Activity> activityInjector =
((HasActivityInjector) application).activityInjector();
checkNotNull(activityInjector, "%s.activityInjector() returned null", application.getClass());
// 3
activityInjector.inject(activity);
复制代码
}
在注释1处,会先判断当前的application是否实现了HasActivityInjector这个接口,如果没有,则抛出RuntimeException。如果有,会继续在注释2处调用application的activityInjector()方法得到DispatchingAndroidInjector实例。最后,在注释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<T> factory = (AndroidInjector.Factory<T>) factoryProvider.get();
try {
// 3
AndroidInjector<T> 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<T> create(T instance) {
seedInstance(instance);
return build();
}
复制代码
看到这里,我相信看过第一个问题的同学已经明白后面是怎么回事了。在create()方法中,我们首先MainActivitySubcomponentBuilder的seedInstance()将MainActivity实例注入,然后再调用它的build()方法新建了一个MainActivitySubcomponentImpl实例返回。
最后,在注释4处,执行了MainActivitySubcomponentImpl的inject()方法:
private final class MainActivitySubcomponentImpl
implements AbstractAllActivityModule_ContributesMainActivityInjector
.MainActivitySubcomponent {
private MainPresenter getMainPresenter() {