Android主流三方库源码分析(8、深刻理解Dagger2源码)

前言

成为一名优秀的Android开发,须要一份完备的知识体系,在这里,让咱们一块儿成长为本身所想的那样~。

上一篇,笔者详细地分析了Android中的依赖注入框架ButterKnife,使用它帮助咱们解决了重复编写findViewById和setOnclickListener的繁琐。众所周知,当项目愈来愈大时,类之间的调用层次会愈来愈深,而且有些类是Activity/Fragment,有些是单例,并且它们的生命周期也不是一致的,因此建立这些对象时要处理的各个对象的依赖关系和生命周期时的任务会很繁重,所以,为了解决这个问题Dagger2应运而生。相比ButterKnife的轻量级使用,Dagger2会显得更重量级和锋利一些,它可以掌控全局,对项目中几乎全部的依赖进行集成管理。若是有对Binder架构体系比较了解的朋友应该知道,其中的服务大管家ServiceManager负责全部的服务(引导服务、核心服务、其它服务)的管理,而Dagger2其实就是将项目中的依赖进行了集成管理。下面,笔者来跟你们一块儿探索Dagger2的内部实现机制,看看它是如何进行依赖管理的。git

Dagger2其实同RxJava同样,是一种多平台通用的库。因为Dagger2的通用写法比较繁琐,所以,Google推出了适用于Android平台的Dagger.Android用法。本文,将基于Dagger.Android的源码对Dagger2内部的实现机制进行探索。github

1、预备知识

鉴于Dagger有必定的上手成本,这里首先带你们复习一下本篇源码分析可能会涉及到的相关基础知识点,以此下降阅读难度。json

一、@Inject

告诉dagger这个字段或类须要依赖注入,而后在须要依赖的地方使用这个注解,dagger会自动生成这个构造器的实例。微信

获取所需依赖:

  • 全局变量注入
  • 方法注入

提供所需实例:

  • 构造器注入(若是有多个构造函数,只能注解一个,不然编译报错)

二、@Module

类注解,表示此类的方法是提供依赖的,它告诉dagger在哪能够找到依赖。用于不能用@Inject提供依赖的地方,如第三方库提供的类,基本数据类型等不能修改源码的状况。架构

注意:Dagger2会优先在@Module注解的类上查找依赖,没有的状况才会去查询类的@Inject构造方法app

三、@Singleton

声明这是一个单例,在确保只有一个Component而且再也不从新build()以后,对象只会被初始化一次,以后的每次都会被注入相同的对象,它就是一个内置的做用域。框架

对于@Singleton,你们可能会产生一些误解,这里详细阐述下:ide

  • Singleton容易给人形成一种误解就是用Singleton注解后在整个Java代码中都是单例,但实际上他和Scope同样,只是在同一个Component是单例。也就是说,若是从新调用了component的build()方法,即便使用了Singleton注解了,但仍然获取的是不一样的对象。
  • 它代表了**@Singleton注解只是声明了这是一个单例,为的只是提升代码可读性,其实真正控制对象生命周期的仍是Component**。同理,自定义的@ActivityScope 、@ApplicationScope也仅仅是一个声明的做用,真正控制对象生命周期的仍是Component

四、@Providers

只在@Module中使用,用于提供构造好的实例。通常与@Singleton搭配,用单例方法的形式对外提供依赖,是一种替代@Inject注解构造方法的方式。函数

注意:源码分析

  • 使用了@Providers的方法应使用provide做为前缀,使用了@Module的类应使用Module做为后缀。
  • 若是@Providers方法或@Inject构造方法有参数,要保证它可以被dagger获取到,好比经过其它@Providers方法或者@Inject注解构造器的形式获得

五、@Component

@Component做为Dagger2的容器总管,它拥有着@Inject与@Module的全部依赖。同时,它也是一枚注射器,用于获取所需依赖和提供所需依赖的桥梁。这里的桥梁即指@Inject和@Module(或@Inject构造方法)之间的桥梁。定义时须要列出响应的Module组成,此外,还可使用dependencies继承父Component。

Component与Module的区别:

Component既是注射器也是一个容器总管,而module则是做为容器总管Component的子容器,实质是一个用于提供依赖的模块。

六、@Scope

注解做用域,经过自定义注解限定对象做用范围,加强可读性

@Scope有两种经常使用的使用场景:

  • 模拟Singleton表明全局单例,与Component生命周期关联
  • 模拟局部单例,如登陆到退出登陆期间

七、@Qualifier

限定符,利用它定义注解类以用于区分类的不一样实例。例如:2个方法返回不一样的Person对象,好比说小明和小华,为了区分,使用@Qualifier定义的注解类。

八、dependencies

使用它表示ChildComponent依赖于FatherComponent,以下所示:

@Component(modules = ChildModule.class, dependencies = FatherComponent.class)
public interface ChildComponent {
    ...
}
复制代码

九、@SubComponent

表示是一个子@Component,它能将应用的不一样部分封装起来,用来替代@Dependencies

回顾完Dagger2的基础知识,下面咱们要启动发动机了。

2、简单示例(取自AwesomeWanAndroid

一、首先,建立一个BaseActivityComponent的Subcomponent:

@Subcomponent(modules = {AndroidInjectionModule.class})
public interface BaseActivityComponent extends AndroidInjector<BaseActivity> {

    @Subcomponent.Builder
    abstract class BaseBuilder extends AndroidInjector.Builder<BaseActivity>{
    }
}
复制代码

这里必需要注解成@Subcomponent.Builder表示是顶级@Subcomponent的内部类。AndroidInjector.Builder的泛型指定了BaseActivity,即表示每个继承于BaseActivity的Activity都继承于同一个子组件(BaseActivityComponent)。

二、而后,建立一个将会导入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维护

三、接着,配置项目的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。

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

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

public abstract class BaseActivity<T extends AbstractPresenter> 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;
    }

    ...
    
}
复制代码

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

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

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

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

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

3、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<MainActivity> {
    @Subcomponent.Builder
    abstract class Builder extends
    AndroidInjector.Builder<MainActivity> {}
}
复制代码

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

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

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

public interface AndroidInjector<T> {

    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 <T extends AbstractPresenter> void injectMPresenter(
  BaseActivity<T> instance, T mPresenter) {
    instance.mPresenter = mPresenter;
}
复制代码

能够看到,这里直接将须要的mPresenter实例赋值给了BaseActivity的mPresenter,固然,这里实际上是指的BaseActivity的子类MainActivity,其它的xxxActivity的依赖管理机制都是如此。

4、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<Activity> 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 <T> DispatchingAndroidInjector<T> 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<Activity> mAndroidInjector) {
    instance.mAndroidInjector = mAndroidInjector;
}
复制代码

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

5、在目标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<T> implements AndroidInjector.Factory<T> {
    @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() {
        // 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;
    }
复制代码

这里的逻辑已经在问题一的最后部分详细讲解了,最后,会在注释3处调用BaseActivity_MembersInjector的injectMPresenter()方法:

public static <T extends AbstractPresenter> void injectMPresenter(
  BaseActivity<T> instance, T mPresenter) {
    instance.mPresenter = mPresenter;
}
复制代码

这样,就将mPresenter对象赋值给了当前Activity对象的mPresenter全局变量中了。至此,Dagger.Android的核心源码分析就结束了。

5、总结

相比于ButterKnife,Dagger是一个锋利的全局依赖注入管理框架,它主要用来管理对象的依赖关系和生命周期,当项目愈来愈大时,类之间的调用层次会愈来愈深,而且有些类是Activity或Fragment,有些是单例,并且它们的生命周期不一致,因此建立所需对象时须要处理的各个对象的依赖关系和生命周期时的任务会很繁重。所以,使用Dagger会大大减轻这方面的工做量。虽然它的学习成本比较高,并且须要写必定的模板类,可是,对于越大的项目来讲,Dagger越值得被须要。下一篇,即是Android主流三方库源码分析系列的终结篇了,笔者将会对Android中的事件总线框架EventBus源码进行深刻的分析,敬请期待~

参考连接:

一、Dagger V2.1.5 源码

二、Android进阶之光

三、告别Dagger2模板代码:DaggerAndroid原理解析

四、Android Dagger2 从零单排

Contanct Me

● 微信:

欢迎关注个人微信:bcce5360

● 微信群:

微信群若是不能扫码加入,麻烦你们想进微信群的朋友们,加我微信拉你进群。

● QQ群:

2千人QQ群,Awesome-Android学习交流群,QQ群号:959936182, 欢迎你们加入~

About me

很感谢您阅读这篇文章,但愿您能将它分享给您的朋友或技术群,这对我意义重大。

但愿咱们能成为朋友,在 Github掘金上一块儿分享知识。

相关文章
相关标签/搜索