[译] 全新 Android 注入器:Dagger 2(一,retrofit原理面试

本文详细介绍了Dagger2.10版本中如何使用依赖注入,包括AppComponent的构建和Activity的注入,强调了类不应关心注入方式的原则,并展示了Component、Subcomponent和Module在Android应用架构中的角色。
摘要由CSDN通过智能技术生成

Dagger 2.10 之前,Dagger 2 是这样用的:

((MyApplication) getApplication())
.getAppComponent()
.myActivity(new MyActivityModule(userId))
.build()
.inject(this);

这会有什么问题呢?我们想用依赖注入,但是依赖注入的核心原则是什么?

一个类不应该关心它是如何被注入的

因此我们必须把这些 Builder 方法和 Module 实例创建部分去掉。

示例工程

我创建的示例工程中没做什么,我想让它尽可能地简单。它里面仅包含 MainActivityDetailActivity 两个 Activity,它们都注入到了相应的 Presenter 实现类并且请求了网络接口(并不是真的发起了 HTTP 请求,我只是写了一个假方法)。

准备工作

在 build.gradle 中加入以下依赖:

compile ‘com.google.dagger🗡2.11-rc2’
annotationProcessor ‘com.google.dagger:dagger-compiler:2.11-rc2’
compile ‘com.google.dagger:dagger-android-support:2.11-rc2’

工程包结构

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

Application 类利用 AppComponent 构建了一张图谱。AppComponent 类的头部都被加上 @Component 注解,当 AppComponent 利用它的 Module 进行构建的时候,我们将得到一张拥有所有所需实例对象的图谱。举个例子,当 App Module 提供了ApiService,我们在构建拥有 App Module 的 Component 时将会得到 ApiService 实例对象。

如果我们想将 Activity 加入到 Dagger 图谱中从而能够直接从父 Compponent 直接获取所需实例,我们只需简单地将 Activity 加上 @Subcomponent 注解即可。在我们的示例中,DetailActivityComponentMainActivityComponent 类都被加上了 @Subcomponent 注解。最后我们还有一个必需步骤,我们需要告诉父 Component 相关的子 Component 信息,因此所有的根 Compponent 都能知道它所有的子 Component。

先别着急,我后面会解释 @Subcomponent@Component 以及 DispatchActivity 都是什么的。现在只是想让你对 @Component@Subcomponent 有一个大概了解。

@Component and @Component.Builder

@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
ActivityBuilder.class})
public interface AppComponent {

@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
AppComponent build();
}

void inject(AndroidSampleApp app);
}

**@Component:**Component 是一个图谱。当我们构建一个 Component时,Component 将利用 Module 提供被注入的实例对象。

**@Component.Builder:**我们可能需要绑定一些实例对象到 Component 中,这种情况我们可以通过创建一个带 @Component.Builder 注解的接口,然后就可以向 builder 中任意添加我们想要的方法。在我的示例中,我想将 Application 加入到 AppComponent中。

注意:如果你想为你的 Component 创建一个 Builder,那你的 Builder 接口中需要有一个返回类型为你所创建的 Component 的 builder() 方法。

注入 AppComponent

DaggerAppComponent
.builder()
.application(this)
.build()
.inject(this);

从上面的代码可以看出,我们将 Application 实例绑定到了 Dagger 图谱中。

我想大家已经对 @Component.Builder@Component 有了一定的认识,下面我想说说工程的结构。

Component/Module 结构

使用 Dagger 的时候我们可以将 App 分为三层:

  • Application Component
  • Activity Components
  • Fragment Components
Application Component

@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
ActivityBuilder.class})
public interface AppComponent {

@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
AppComponent build();
}

void inject(AndroidSampleApp app);
}

每个 Android 应用都有一个 Application 类,这就是为什么我也有一个 Application Component 的原因。这个 Component 表示是为应用层面提供实例的 (例如 OkHttp, Database, SharedPrefs)。这个 Component 是 Dagger 图谱的根,在我们的应用中 Application Component 提供了三个 Module

  • AndroidInjectionModule:这个类不是我们写的,它是 Dagger 2.10 中的一个内部类,通过给定的 Module 为我们提供了 Activity 和 Fragment。
  • ActivityBuilder:我们自己创建的 Module,这个 Module 是给 Dagger 用的,我们将所有的 Activity 映射都放在了这里。Dagger 在编译期间能获取到所有的 Activity,我们的 App 中有 MainActivity 和 DetailActivity 两个 Activity,因此我将这两个 Activity 都放在这里。

@Module
public abstract class ActivityBuilder {

@Binds
@IntoMap
@ActivityKey(MainActivity.class)
abstract AndroidInjector.Factory<? extends Activity> bindMainActivity(MainActivityComponent.Builder builder);

@Binds
@IntoMap
@ActivityKey(DetailActivity.class)
abstract AndroidInjector.Factory<? extends Activity> bindDetailActivity(DetailActivityComponent.Builder builder);

}

  • AppModule:我们在这里提供了 retrofit、okhttp、持久化数据库、SharedPrefs。其中有一个很重要的细节,我们必须将子 Component 加入到 AppModule 中,这样 Dagger 图谱才能识别。

@Module(subcomponents = {
MainActivityComponent.class,
DetailActivityComponent.class})
public class AppModule {

@Provides
@Singleton
Context provideContext(Application application) {
return application;
}

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

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

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

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

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
img

最后

Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。

人生不可能一帆风顺,有高峰自然有低谷,要相信,那些打不倒我们的,终将使我们更强大,要做自己的摆渡人。

资源持续更新中,欢迎大家一起学习和探讨。

Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。

人生不可能一帆风顺,有高峰自然有低谷,要相信,那些打不倒我们的,终将使我们更强大,要做自己的摆渡人。

资源持续更新中,欢迎大家一起学习和探讨。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值