概述
api、provided、compile、implementation 都是 gradle 添加依赖时的选项,不同的选项表示不同的依赖关系。
其中 api、implementation 是 Gradle 3.4 引入的新的依赖配置,用来代替 compile 依赖配置。其中 api 和以前的 compile 依赖配置是一样的。使用 api/compile 的依赖方式,会向外界暴露本模块所依赖的库的接口,使用 implementation 则不会。
解决了什么问题?
为什么要做这样的修改呢?使用 implementation 依赖配置,可以显著减少构建的时间。
考虑这样的场景,有如下六个模块:

D、E、F 三个模块都依赖了 Lib 库。
假设 D、E、F 三个模块都以 implementation 的方式引用 Lib 库,那么上层的 A,B,C 三个模块在编译期都无法引用到 Lib 库中的内容。因此当 Lib 发生变化的时候,只有 D E F 这三个模块需要重新编译,A,B,C 则不需要(因为 DEF 三个模块对外的接口都没有改变)。
假设 D、E、F 三个模块都以 compile/api 的方式引用 Lib 库(对外暴露了自己引用的库的接口),那么无论上层的 A,B,C 三个模块对 D、E、F 模块的依赖是 compile、api 方式还是 implementation 方式,它们(A、B、C)都可以引用到 Lib 库中的内容。这种情况下当 Lib 发生变化的时候,A B C D E F 这三个模块都需要重新编译。
Public 可以
其它变化
在该版本中,官方团队也把之前命名的不规范的地方修改了,provided 改成了 compileOnly,apk 改为了 runtimeOnly。改变的只是名称,功能没变。
compileOnly 的使用场景
包括但是不限于下面的两种:
- 编译时所需的依赖性,但在运行时从不需要,例如纯源注释或注释处理器;
- API 在编译时需要,但其实现由消费库,应用程序或运行时环境提供的依赖项。
runtimeOnly 的使用场景
依赖项仅在运行时对模块及其消费者可用。
小结
| 新配置 | 已弃用配置 | 行为 |
|---|---|---|
implementation |
compile |
依赖项在编译时对模块可用,并且仅在运行时对模块的消费者可用。 对于大型多项目构建,使用 implementation 而不是 api/compile 可以显著缩短构建时间,因为它可以减少构建系统需要重新编译的项目量。 大多数应用和测试模块都应使用此配置。 |
api |
compile |
依赖项在编译时对模块可用,并且在编译时和运行时还对模块的消费者可用。 此配置的行为类似于 compile(现在已弃用),一般情况下,您应当仅在库模块中使用它。 应用模块应使用 implementation,除非您想要将其 API 公开给单独的测试模块。 |
compileOnly |
provided |
依赖项仅在编译时对模块可用,并且在编译或运行时对其消费者不可用。 此配置的行为类似于 provided(现在已弃用)。 |
runtimeOnly |
apk |
依赖项仅在运行时对模块及其消费者可用。 此配置的行为类似于 apk(现在已弃用)。 |
注:
compile、provided和apk目前仍然可用。 不过,它们将在下一个主要版本的 Android 插件中消失。
日常开发中一般都是用 implementation,部分情况下会用到 api,其他的依赖方式一般不怎么用到。记住 compile、api 依赖方式是「传递性的」,而 implementation 依赖方式的是「非传递性」的。
参考资料与学习资源推荐
由于本人水平有限,可能出于误解或者笔误难免出错,如果发现有问题或者对文中内容存在疑问请在下面评论区告诉我,谢谢!