1)、新的 Lint 检查依赖项配置
增加了新的依赖项配置 lintPublish,并更改了原有 lintChecks 的行为,它们的作用分别如下所示:
lintChecks
:仅用于在本地构建项目时运行的 Lint 检查。lintPublish
:在已发布的 AAR 中启用 Lint 检查,这样使用此 AAR 的项目也会应用那些 Lint 检查。
其示例代码如下所示:
dependencies {
// Executes lint checks from the ‘:lint’ project at build time.
lintChecks project(’:lint’)
// Packages lint checks from the ‘:lintpublish’ in the published AAR.
lintPublish project(’:lintpublish’)
}
2)、Android 免安装应用功能插件弃用警告
在之前的版本可以使用 com.android.feature
插件构建免安装应用,现在建议使用动态功能插件,这样便可以通过单个 Android App Bundle 发布安装版应用和免安装应用。
3)、R8 默认处于启用状态
R8 将 desugar(脱糖:将 .class 字节码转换为 .dex 字节码的过程)、压缩、混淆、优化和 dex 处理整合到了一个步骤中,从而显著提升了构建性能。R8 是在 Android Gradle Plugin V3.2.0 中引入的,对于使用插件 V3.4.0 及更高版本的应用和 Android 库项目来说,R8 已经默认处于启用状态。
R8 引入之前的编译流程
R8 引入之后的编译流程
可以看到,R8 组合了 Proguard、D8 的功能。如果遇到因 R8 导致的编译失败的问题,可以配置以下代码停用 R8:
Disables R8 for Android Library modules only.
android.enableR8.libraries = false
Disables R8 for all modules.
android.enableR8 = false
3)、弃用 ndkCompile
此时使用 ndkBuild 编译原生库会收到构建错误。我们应该 使用 CMake 或 ndk-build 将 C 和 C++ 代码添加到项目中。
3、Android Gradle Plugin V3.3.0(2019 年 1 月)
1)、为库项目更快地生成 R 类
在老版本中,Android Gradle 插件会为项目的每个依赖项生成一个 R.java 文件,然后将这些 R 类和应用的其他类一起编译。现在,插件会直接生成包含应用的已编译 R 类的 JAR,而不会先编译中间的 R.java 类。这不仅可以显著提升包含多个库子项目和依赖项的项目的编译性能,还可以加快在 Android Studio 中索引文件的速度。
4、Android Gradle Plugin V3.2.0(2018 年 9 月)
新的代码压缩器 R8
R8 是一种执行代码压缩和混淆的新工具,替代了 ProGuard。我们只需将以下代码添加到项目的 gradle.properties 文件中,即可开始使用 R8 的预览版本:
android.enableR8 = true
使用 D8 进行 desugar 的功能现已默认处于启用状态
5、Android Gradle Plugin V3.1.0(2018 年 3 月)
新的 DEX 编译器 (D8)
默认情况下,Android Studio 此时会使用名为 D8 的新 DEX 编译器。DEX 编译是指针对 ART (对于较早版本的 Android,则针对 Dalvik)将 .class 字节码转换为 .dex 字节码的过程。与之前的编译器(DX)相比,D8 的编译速度更快,输出的 DEX 文件更小,同时却能保持相同甚至更出色的应用运行时性能。
如果在使用 D8 的过程中出现了问题,可以在 gradle.properties 配置以下代码暂时停用 D8 并使用 DX:
android.enableD8=false
6、Android Gradle Plugin V3.0.0(2017 年 10 月)
1)、通过精细控制的任务图提升了多模块项目的并行性。
更改依赖项时,Gradle 通过不重新编译那些无法被访问的依赖项 API 模块来加快编译速度。此时可以利用 Gradle 的新依赖项配置(implementation、api、compileOnly 和 runtimeOnly)限制哪些依赖项会将其 API 泄露给其他模块。
2)、借助每个类的 dex 处理,可加快增量编译速度。
每个类现在都会编译成单独的 DEX 文件,并且只会对修改过的类重新进行 dex 处理。
3)、启用 Gradle 编译缓存优化某些任务来使用缓存的输出
启用 Gradle 编译缓存能够优化某些任务来使用缓存的输出,从而加快编译速度。
4)、AAPT2 默认已启用并改进了增量资源处理
如果在使用 AAPT2 时遇到了问题,我们可以停用 AAPT2,在 gradle.properties 文件中设置如下代码:
android.enableAapt2=false
然后,通过在命令行中运行 ./gradlew --stop 来重启 Gradle 守护进程。
7、Android Gradle Plugin V2.3.0(2017 年 2 月)
1)、增加编译缓存
存储编译项目时 Android 插件生成的特定输出。使用缓存时,编译插件的速度会明显加快,因为编译系统在进行后续编译时可以直接重用这些缓存文件,而不必重新创建。此外,我们也可以 使用 cleanBuildCache Task 去清除编译缓存。
更老版本的的更新细节请查阅 gradle-plugin。
三、Gradle 构建核心流程解析
当我们输入 ./gradlew/gradle … 命令之后,一个 Gradle 构建就开始了。它包含如下 三个步骤
:
- 1)、首先,初始化 Gradle 构建框架自身。
- 2)、然后,把命令行参数包装好送给 DefaultGradleLauncher。
- 3)、最后,触发 DefaultGradleLauncher 中 Gradle 构建的生命周期,并开始执行标准的构建流程。
在开始深入源码之前,我们可以先自顶向下了解下 Gradle 构建的核心流程图,以便对 Gradle 的构建流程建立一个整体的感知。
当我们执行一个 gralde 命令时,便会调用 gradle/wrapper/gradle-wrapper.jar 里面 org.gradle.wrapper.GradleWrapperMain 类的 main 方法,它就是 gradle 的一个入口方法。该方法的核心源码如下所示:
public static void main(String[] args) throws Exception {
…
// 1、索引到 gradle-wrapper.properties 文件中配置的 gradle zip 地址,并由此包装成一个 WrapperExecutor 实例。
WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile);
// 2、使用 wrapperExecutor 实例的 execute 方法执行 gradle 命令。
wrapperExecutor.execute(args, new Install(logger, new Download(logger, “gradlew”, “0”), new PathAssembler(gradleUserHome)), new BootstrapMainStarter());
}
然后,我们继续看看 wrapperExecutor 的 execute 方法,源码如下所示:
public void execute(String[] args, Install install, BootstrapMainStarter bootstrapMainStarter) throws Exception {
// 1、下载 gradle wrapper 需要的依赖与源码。
File gradleHome = ins