安卓平台上的依赖注入(一)
刚开始学习软件工程的时候,我们经常会碰到像这样的事情:
软件应该符合 SOLID 原则。
但这句话实际是什么意思?让我们看看 SOLID 中每个字母在架构里所代表的重要含义,例如:
- S - 单职责原则
- O - 开闭原则
- L - Liskov 替换原则
- I - 接口分离原则
- D - 依赖反转原则 这也是依赖注入dependency injection的核心概念。
简单来说,我们需要提供一个类,这个类有它所需要的所有对象,以便实现其功能。
概述
依赖注入听起来像是描述非常复杂的东西的一个术语,但实际上它很简单,看下面这个例子你就明白了:
class NoDependencyInjection {
private Dependency d;
public NoDependencyInjection() {
d = new Dependency();
}
}
class DependencyInjection {
private Dependency d;
public DependencyInjection(Dependency d) {
this.d = d;
}
}
正如我们所见,第一种情况是我们在构造器里创建了依赖对象,但在第二种情况下,它作为参数被传递给构造器,这就是我们所说的依赖注入dependency injection。这样做是为了让我们所写的类不依靠特定依赖关系的实现,却能直接使用它。
参数传递的目标是构造器,我们就称之为构造器依赖注入;或者是某个方法,就称之为方法依赖注入:
class Example {
private ConstructorDependency cd;
private MethodDependency md;
Example(ConstructorDependency cd) {
this.cd = cd; //Constructor Dependency Injection
}
public setMethodDependency(MethodDependency md) {
this.md = md; //Method Dependency Injection
}
}
要是你想总体深入地了解依赖注入,可以看看由 Dan Lew 发表的精彩的演讲,事实上是这个演讲启迪了这篇概述。
在 Android 平台,当需要框架来处理依赖注入这个特殊的问题时,我们有不同的选择,其中最有名的框架就是 Dagger 2。它最开始是由 Square 公司(LCTT 译注:Square 是美国一家移动支付公司)的一些很棒的开发者开发出来的,然后慢慢发展成由 Google 自己开发。首先开发出来的是 Dagger 1,然后 Big G 接手这个项目发布了第二个版本,做了很多改动,比如以注解annotation为基础,在编译的时候完成其任务。
导入框架
安装 Dagger 并不难,但需要导入 android-apt
插件,通过向项目的根目录下的 build.gradle
文件中添加它的依赖关系:
buildscript{
...
dependencies{
...
classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’
}
}
然后,我们需要将 android-apt
插件应用到项目 build.gradle
文件,放在文件顶部 Android application 那一句的下一行:
apply plugin: ‘com.neenbedankt.android-apt’
这个时候,我们只用添加依赖关系,然后就能使用库及其注解annotation了:
dependencies{
...
compile ‘com.google.dagger:dagger:2.6’
apt ‘com.google.dagger:dagger-compiler:2.6’
provided ‘javax.annotation:jsr250-api:1.0’
}
需要加上最后一个依赖关系是因为 @Generated 注解在 Android 里还不可用,但它是原生的 Java 注解。
Dagger 模块
要注入依赖,首先需要告诉框架我们能提供什么(比如说上下文)以及特定的对象应该怎样创建。为了完成注入,我们用 @Module
注释对一个特殊的类进行了注解(这样 Dagger 就能识别它了),寻找@Provide
注解的方法,生成图表,能够返回我们所请求的对象。
看下面的例子,这里我们创建了一个模块,它会返回给我们 ConnectivityManager
,所以我们要把Context
对象传给这个模块的构造器。
@Module
public class ApplicationModule {
private final Context context;
public ApplicationModule(Context context) {
this.context = context;
}
@Provides @Singleton
public Context providesContext() {
return context;
}
@Provides @Singleton
public ConnectivityManager providesConnectivityManager(Context context) {
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
}
Dagger 中十分有意思的一点是简单地注解一个方法来提供一个单例(Singleton),就能处理所有从 Java 中继承过来的问题。
组件
当我们有一个模块的时候,我们需要告诉 Dagger 想把依赖注入到哪里:我们在一个组件Component里完成依赖注入,这是一个我们特别创建的特殊注解接口。我们在这个接口里创造不同的方法,而接口的参数是我们想注入依赖关系的类。
下面给出一个例子并告诉 Dagger 我们想要 MainActivity
类能够接受 ConnectivityManager
(或者在图表里的其它依赖对象)。我们只要做类似以下的事:
@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
void inject(MainActivity activity);
}
正如我们所见,@Component 注解有几个参数,一个是所支持的模块的数组,代表它能提供的依赖。这里既可以是
Context
也可以是ConnectivityManager
,因为它们在ApplicationModule
类中有声明。
用法
这时,我们要做的是尽快创建组件(比如在应用的 onCreate
阶段)并返回它,那么类就能用它来注入依赖了:
为了让框架自动生成
DaggerApplicationComponent
,我们需要构建项目以便 Dagger 能够扫描我们的代码,并生成我们需要的部分。
在 MainActivity
里,我们要做的两件事是用 @Inject
注解符对想要注入的属性进行注解,调用我们在 ApplicationComponent
接口中声明的方法(请注意后面一部分会因我们使用的注入类型的不同而变化,但这里简单起见我们不去管它),然后依赖就被注入了,我们就能自由使用他们:
public class MainActivity extends AppCompatActivity {
@Inject
ConnectivityManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
((App) getApplication()).getComponent().inject(this);
}
}
总结
当然了,我们可以手动注入依赖,管理所有不同的对象,但 Dagger 消除了很多比如模板这样的“噪声”,给我们提供有用的附加品(比如 Singleton
),而仅用 Java 处理将会很糟糕。
原文发布时间为:2017-12-27
本文来自云栖社区合作伙伴“Linux中国”

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Zxing 的集成 ---- Maven 对应 Gradle 的写法
刚刚想耍耍二维码,想到了zxing和zbar,又想到zxing是Google老爹的,想想就算了吧,虽然zbar快但是识别错误率也高不少.随手Google了下*zxing 集成*好像都是说什么拷贝项目到自己的工程中,我不信Gradle集成这么方便了为何不用.于是我来到zxing的 Github 主页https://github.com/zxing/zxing,在README的引导下来到Get Start页面,里面有如下说明: Maven core/, javase/, android-integration and zxingorg can be used directly in a Maven-based project without any download or installation. Instead, add as dependencies from groupID com.google.zxing artifactIDs core, javase, android-integration or zxingorg: <dependencies> ... <...
- 下一篇
详解使用 fastboot 为 Android 刷入原厂镜像
如果你的手机有一个解锁的bootloader的话,你可以用fastboot命令来刷入原厂镜像。听起来这好像是外行弄不懂的东西,但是当你需要升级被root过的设备,修理坏掉的手机,恢复到原生系统,或者是比别人更早的享受 Android 更新时,它可是最好的办法。 和ADB类似,fastboot 是一个强大的 Android 命令行工具。这听起来可能会很恐怖 —— 别担心,一旦你了解了它,你就会知道 Android 的内部工作原理,以及如何解决最常见的问题。 关于三星设备的注释 下面的指南对于 Nexus、Pixel、HTC 以及 Motorola 的大多数设备,以及其他众多厂商的手机和平板电脑都适用。但是,三星的设备有自己的刷机软件,所以你的 Galaxy 设备并不支持 Fastboot。对于三星的设备,最好使用Odin来进行刷机工作,我们在下文的链接中提供了相关指南。 第一步 在你的电脑上安装 ADB 和 Fastboot 首先,你需要在你的电脑上安装 ADB 和 Fastboot,只有有了它们你才能使用 Fastboot 命令刷入镜像。网上有不少“一键安装版”或者“绿色版”的 ADB...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7设置SWAP分区,小内存服务器的救世主
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Hadoop3单机部署,实现最简伪集群