[Android] Implementation vs API dependency
原文链接:
https://jeroenmols.com/blog/2017/06/14/androidstudio3/
https://blog.csdn.net/lonewolf521125/article/details/78482880
更新到 Android Studio 3.0 之后,构建多 module 结构的项目速度有很大的提升,但不幸的是这同样意为着 Gradle 插件的 API 也做了修改.
本文将详细的介绍本次改变的优点,以及使你能够顺畅应用升级。
目前的问题
为了理解 Gradle plugin 2.0 编译系统的限制,现在考虑下面这个拥有多层引用 module 的工程:

现在请考虑一下最下面的 module A,对 module A 一般来讲会有两种变化:
- Implementation change(内部实现的更改):
内部更改,未涉及到对外的接口变更- ABI change(Application binary interface change;对外接口的更改):
module A 对外的接口做了修改
注意:下文中,所有重编译的 module 都会用红色高亮显示。
Implementation change
既然 module A 的对外接口未做更改,那么 Gradle 自然也只对 module A 做重编译。所有 module A 的消费者(实际就是直接或间接引用到 module A 的其他 module)都不会受到影响。

在此场景下没有什么问题。
ABI change
当 module A 的对外接口做更改的时候,module A 的直接消费者 B1、B2、B3(也就是直接引用到 module A 的其他 module)也需要重编译。

但是 A 的直接消费者们(B1、B2、B3)有可能通过自己( B1、B2、B3 )的接口将 A 暴露出去!所以为了保险起见,这些引用到 B1、B2、B3 的 module (C1、C2、C3) 也需要从编译。同样的引用到 C1、C2、C3 也一样需要重新编译…
因此 Gradle 实际上需要对所有的 module 进行重编译。

现在我们遇到了一个大问题:
一个代码的更改引发了所有 module 的重编译。
本问题最根本的原因是 Gradle 并不知道你是否通过一个 module 将其引用到的另一个 module 接口给泄露出去了(例如 Gradle 并不知道你是否在 module B1 中将 A module 的接口暴露给了 App)。
救星来了(Android Gradle plugin 3.0)
现在最新一版的 Android Gradle 插件需要你明确的指出你是否要将某 module 的接口暴露出去。基于此它可以在判断某 module 是否需要重编译时做出正确的选择。
compile 已被弃用,并由两个新的替代:
api:通过你自己的接口将你引用到的 module 接口暴露出去供其他 module 使用,含义上实际与 compile 一致
比如:对于 B1 module ,如果其引用 A module 时使用了 api ,那么 C1 就可以使用到 A module 的接口
implementation:仅仅将你引用到的此 module 在内部使用,而不将其接口暴露给外部
比如:对于 B1 module,如果其引用 A module 时使用了 implementation,那么 C1 无法使用到 A module 的接口
基于以上,现在你就可以明确的告诉 Gradle 某个 module 在它引用的 module 更改时进行重编译,在它引用的 module 未更改时不做重编译。
示例如下:
dependencies {
//当 legofy 对外接口更新时,重编译本 module 以及所有引用此 module 的 module
api project(':legofy')
//当 landscapevideocamera 对外接口更新时,仅仅重编译本 module
implementation project(':landscapevideocamera:1.0.0')
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
迁移指南
(废弃 compile 改用 api 和 implementation 形式的操作指南)
理论上你可以将所有的 compile 都修改为 api(运行上不会报任何错误),但是这种方式还是可能会因为一个代码的变动引发所有 module 的重编译:

所以最好的方式是尽量使用 implementation 替换 compile ,当且仅当想将你引用的 module 暴露出去的时候再用 api,按照这种方式会减少很多重编译。

希望这篇文章能尽量阐明 api 与 implementation 之间模糊的含义
(至于官方的迁移文档,呵呵哒)
其他的依赖配置
团队也利用这次变更最终给予其他配置以适当的名称:
- provided 配置现在改成了 compileOnly
- apk 配置现在改成了 runtimeOnly
就像之前一样,你可以将配置与 variants 进行组合:debugApi、testImplementation 等
#其他的迁移项目
~~Android Studio 3.0 包含了许多终于得到解决的其他改进,我最喜爱的是:~~
* 所有的 google dependencies 在 Maven 在线仓库中都可以被访问到
~~。。。~~
详细信息:
https://developer.android.com/studio/preview/features/new-android-plugin-migration.html
总结:
为了提升多项目结构的构建速度, Android Gradle plugin 需要一个突破性的提升。尽量使用 implementation (因为它会引发更少的 module 重编译)
---------------------
本文来自 杨筱毅 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/lonewolf521125/article/details/78482880?utm_source=copy
[Android] Implementation vs API dependency的更多相关文章
- Android Studio3.x新的依赖方式(implementation、api、compileOnly)
https://blog.csdn.net/yuzhiqiang_1993/article/details/78366985?locationNum=6&fps=1 Android Studi ...
- android studio compile api implementation 区别
compile与api 二者等同,无区别 implementation与compile或implementation与api implementation编译的依赖只作用于当前的module.即APP ...
- 懒人模式开启Android模块自动化Api之旅
推荐阅读: 滴滴Booster移动App质量优化框架-学习之旅 一 Android 模块Api化演练 不一样视角的Glide剖析(一) 在将业务进行模块化时,避免不了模块页面路由和模块通信, 大多数我 ...
- Android Error:Unable to find method 'com.android.build.gradle.api.BaseVariant.getOutputs()Ljava/util/List;'.
问题:Error:Unable to find method 'com.android.build.gradle.api.BaseVariant.getOutputs()Ljava/util/List ...
- Android SDK之API Level
Android SDK之API Level Android SDK API_LEVEL Platform Version API Level VERSION_CODE Android 4.2, 4.2 ...
- Android 使用Telephony API
Android 使用Telephony API public class TelephonyDemo extends Activity { TextView textOut; TelephonyMan ...
- Android L Camera2 API 使用实例程序汇总
在网上发现几个使用Camera API2开发的实例程序,总结一下方便后续参考: 1.Camera2 Basic : https://github.com/googlesamples/android-C ...
- 申请Android Map 的API Key(v2)的最新申请方式(SHA1密钥)
申请Android Map 的API Key(v2)的最新申请方式(SHA1密钥)具体步骤如下: ...
- 翻译Android USB HOST API
翻译Android USB HOST API 源代码地址:http://developer.android.com/guide/topics/connectivity/usb/host.html 译者 ...
随机推荐
- Spark streaming的正确使用。。
转自http://bit1129.iteye.com/blog/2198531 代码如下: package spark.examples.streaming import java.sql.{Prep ...
- 应用Mongoose开发MongoDB(2)模型(models)
数据模型及基础操作模板 为了使工程结构清晰,将数据模型(Schema, Model)的建立与增删查改的基础操作模板写在一起,命名为数据库设计中的Collection(对应于关系型数据库中的表定义)名, ...
- DFT,DTFT,DFS,FFT区别
学习了数字信号处理之后,被里面的几个名词搞的晕头转向,比如DFT,DTFT,DFS,FFT,FT,FS等,FT和FS属于信号与系统课程的内容,是对连续时间信号的处理,这里就不过多讨论,只解释一 ...
- Node.js包的依赖及版本号(转)
原文: http://www.cnphp6.com/archives/64130 Node.js最重要的一个文件就是package.json,其中的配置参数决定了功能.例如下面就是一个例子 { &q ...
- 关于Sql Server的一些知识点的定义总结
数据库完整性:是指数据库中数据在逻辑上的一致性.正确性.有效性和相容性 实体完整性(Entity Integrity 行完整性):实体完整性指表中行的完整性.主要用于保证操作的数据(记录)非空.唯一 ...
- sublime安装package control 的方法
1.安装sublime3后,点击菜单 view>show console,复制以下代码按回车即可,安装时稍微有些卡,需要耐心等待. import urllib.request,os; pf = ...
- 电子邮件-TCP
参考下图,由于电子邮件是最早应用于网络上的服务,而早期网络的不可靠性,才设计了TCP协议,而邮件必须要保证正确传输,而非高速,所以早期的电子邮件协议 全是基于TCP的,一直持续到现在.
- android listView 点两下才监听到
因为 对应的控件设置了 android:focusableInTouchMode="true" 意思是 触摸模式下 点击第一次 是 获得焦点.===
- 【COGS-2638】数列操作ψ 线段树
题目链接: http://cogs.pro/cogs/problem/problem.php?pid=2638 Solution 用jry推荐的写法即可做到单次$O(log^{2}N)$,不过随机数据 ...
- WEB应用从服务器主动推送Data到客户端有那些方式?
1) html5 websocket 2) WebSocket 通过 Flash 3) XHR长时间连接 4) XHR Multipart Streaming 5) 不可见的Iframe 6 ...