您现在的位置是:首页 >技术交流 >Android主流三方库源码分析:Dagger2网站首页技术交流

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

2501_90498770 2025-03-21 00:01:03
简介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() {
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。