煎饼

煎饼为你分享Android有关的技术文章
不断分享,点滴积累,共同提高

关注微信公众号[developers]
更快的了解新的技术动态

Dagger on Android-从Dagger1到Dagger2

Android上的依赖注入框架(Dependency injections framewords)你可能已经有所了解,在之前的文章中已经详细介绍过Dagger1和Dagger2的使用。自从接触Dagger之后就喜欢上了它,而且Dagger在国外的使用也越来越多,但是我也遇到一些人向我抱怨说:

1、dependency injections frameworks 太慢 而且打乱了之前的逻辑,而且学习使用成本有点高。

2、Android的原生到底有什么问题,需要引入这么一个库并且改变逻辑层的代码实现来解决?

3、有的时候为了简化代码,有可能要去凭空的构建类之间的依赖关系,反而让实现变得繁琐了。

之前有说过,对于刚开始学习Dagger的来说,这些疑问是存在的。

在几年前使用RoboGuice的时候,确实是慢,因为它的所有依赖图表(dependency graph)和验证过程都是在运行时处理的。现在使用Dagger就不是这样了,Dagger是在编译时就把上述工作给处理完了(Roboguice 3 现在也在编译时做了很多工作,可以继续关注一下),当然比手写的代码还是会稍微慢点,但是在Android App上基本可以无视这点。

对于后两个问题,每个人的看法可能不同。在 Dagger on Android-基础篇 一文中已经有说明使用DI能解决的问题。并且在 AirDroid 中使用Dagger 1也没有发现、遇到什么问题,也并没有让实现变得复杂,而是更简单方便了。

当Dagger 2 Snapshot 版本发布后,自己迫不及待地去深入学习、了解了与Dagger1的不同之处,并写下了Android 依赖注入: Dagger 2 实例讲解(一) 一文。直到Dagger 2 正式版发布之后,才着手写了一个录屏应用Lop(豌豆荚下载 源码(第一个版本的源码,之后会继续更新))来更深入的学习使用Dagger2,这个时候就发现Dagger 1的劣势就凸显出来了。

Dagger 2自动解决了Dagger 1中会引起花费时间太多的问题,这点对于稍微大点的Project来说很重要。

ProGuarding

对于已经超过Dex所要求的最大值65k的App,目前的解决方式基本都是使用MultiDex,但是根据它的规则,我在这里建议使用Proguard。因为MultiDex.install(this)这个放在Application.onCreate()中调用的时候,在4.4的Nexus7上会花费4000ms左右的时间(在安装支持MultidDex .so 文件的Lollipop系统的相同设备上只花费了1ms),另外,在使用 gradle assembleDebug 编译的时候基本会花2分钟左右(现在我们编译AirDroid基本都在4-5分钟左右)。为什么会花这么长时间?简单的说就是-MultiDex在我们改变代码后都去会检查一下,然后决定哪些代码放到第一个.dex文件,哪些放到另外的.dex文件。

所以我在这里建议使用Proguard,但是你会发现在proguard规则中并没有简单的方法来处理Dagger 1自动产生的代码。怎么办?在ProGuard with Gradle的最后有介绍 Squad leader,可以使用@Keep or @KeepName来处理。如果不想使用Squad leader,那就将Dagger 1 升级到 Dagger 2吧。

Dagger 2 不需要Proguard 规则,它产生的代码全部可以trace到而且没有使用反射(reflection).

其他

下面的一些点虽说不是很重要,但可以让我们更加坚定的从Dagger1升级到Dagger2

1、Dagger 1 产生的代码非常难懂。我们基本不能看到它内部的实现,而且在Android Studio中使用“find usages”也不能trace到代码。而Dagger2产生的代码就像手写实现的ID,可以更好的理解它是如何实现的。

2、Dagger 2 可能不是很灵活,但是它的API相对Dagger1来说简单很多,学习起来也不是很麻烦。

3、Dagger 2 可以大大减少依赖图表(Dependencies graph)的构建时间。

Dagger 2是Dagger 1.x的增强版,在Dagger 1.x中,@Inject和@Provides annotation 构成了对象的图谱(graph),依靠之间的依赖关系而链接在一起。通过定义好的图谱集(ObjectGraph)可以方便的调用代码。而在Dagger 2中,这种关系被带有无参方法的接口代替,这种方法返回的类型就是所需类型。这种接口的实现是通过@Component 注解且传入modules参数来定义的。

更多Dagger 2的内容将在下一篇介绍。

609

分享本文:

Json特殊格式解析