Android主流三方库源码分析:Dagger2,阿里Android开发手册

@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() {

    // 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 void injectMPresenter(

BaseActivity instance, T mPresenter) {

instance.mPresenter = mPresenter;

}

复制代码




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



### []( )五、总结



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





**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/9883e4d1dcc0149cdd3afbcae70d6c44.png)
![img](https://img-blog.csdnimg.cn/img_convert/6f8ecbf781199d3ff10f4bf9b5429621.png)
![img](https://img-blog.csdnimg.cn/img_convert/73293ee0c3ac0db97197152b5bde2174.png)
![img](https://img-blog.csdnimg.cn/img_convert/53d2c78f3fe258a5ab28918d2940dea6.png)
![img](https://img-blog.csdnimg.cn/img_convert/31f9fba1f745ee1fbbfd80ba7467c553.png)
![img](https://img-blog.csdnimg.cn/img_convert/96114e57d19ff8fd71fb337455f1e00d.png)
![img](https://img-blog.csdnimg.cn/13f2cb2e05a14868a3f0fd6ac81d625c.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)**
![img](https://img-blog.csdnimg.cn/img_convert/987c867ceb553c962cf13cd82a9d2be1.png)



#### 最后是今天给大家分享的一些独家干货:

**【Android开发核心知识点笔记】**

![](https://img-blog.csdnimg.cn/img_convert/43be8b2369869c2ba25d038b49e69fd4.webp?x-oss-process=image/format,png)

**【Android思维脑图(技能树)】**

![](https://img-blog.csdnimg.cn/img_convert/0b2cafab3238263efd60e7864b5938d7.webp?x-oss-process=image/format,png)

**【Android核心高级技术PDF文档,BAT大厂面试真题解析】**

![](https://img-blog.csdnimg.cn/img_convert/4c3c516dca2005acb160dde0689b0441.webp?x-oss-process=image/format,png)

**【Android高级架构视频学习资源】**



> **本文已被[CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》]( )收录**

[**一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)

**AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**

]
[外链图片转存中...(img-ZyhijBys-1712151111964)]
![img](https://img-blog.csdnimg.cn/13f2cb2e05a14868a3f0fd6ac81d625c.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)**
[外链图片转存中...(img-zvHn6PKM-1712151111964)]



#### 最后是今天给大家分享的一些独家干货:

**【Android开发核心知识点笔记】**

[外链图片转存中...(img-F1JDBobs-1712151111965)]

**【Android思维脑图(技能树)】**

[外链图片转存中...(img-Y7tt9Gaq-1712151111965)]

**【Android核心高级技术PDF文档,BAT大厂面试真题解析】**

[外链图片转存中...(img-pMlzS0Eo-1712151111965)]

**【Android高级架构视频学习资源】**



> **本文已被[CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》]( )收录**

[**一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)

**AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值