『构建指北』是探索 Android 构建相关的一系列文章,涵盖了 Gradle 、Android Gradle Plugin 、Kotlin Script 等工具,以及相关架构上的应用。
由于几个月前电脑 CPU 烧了,被迫换了 M1 的 Mac Mini,所以整个开发环境重新搭建了一遍。趁这个机会,我想整理几个基础工具的版本搭配策略、兼容性、以及在 M1 芯片上的表现。对于版本搭配和兼容性的一些讨论不局限于当前使用的版本和平台。
下方提及的版本分别是:
自 AGP 7.0 起,JDK 11 便是最低要求。JDK 11 成为 LTS ( Long-term Support) 版本已经有将近 3 年历史( Sep 2018 ),自身经历了 12 个小版本( 11.0.12 )的迭代目前相对成熟了。作为对比,上一个 LTS 的 JDK 8 2014 年发布,已经陪着我们走过了 7 年时光和 300 个小版本迭代。事实上作为 Android 开发者,即便目前项目是 Java 为主的情况,一般 Language Level 也仅 target to 1.8 (一些 9-12 的特性 D8 、R8 有支持,Android 11 12 也有融入)。Android 官方虽然说不会放弃 Java,但实际上对 Kotlin 的支持确实更给力。
从这个角度来看,JDK 11 带来给我们的更多是:
而 JDK 的升级策略我认为是:
在 M1 Mac 上,由于 Oracle 还未有的 ARM64 版本,所以目前主流的做法是安装 Azul 维护的 Zulu JDK11
。
需要注意的是,常用的 JDK 管理工具 SDKMAN!
在我的测试中依旧跑在 Rosetta 2
的转译环境中。这会造成即便你是安装的 Zulu JDK11
,通过 SDKMAN!
的脚本启动依然会显示 Gradle java
的进程跑在 Intel ABI 下。故目前建议从官网下载安装,等后续配套工具支持后再考虑切换。
Kotlin 的版本搭配限制相对不多,一般我考虑三个点:
1.4.0
,1.5.0
,这条其实广泛适用于各类 Library ;1.4.31
的 Kotlin ( 7.2 RC 则跳到 1.5.21
了);关于最后一点,如果使用的 Kotlin 版本和 Gradle bundle 的不一致,会出现如下 Warning:
w: Runtime JAR files in the classpath should have the same version. >These files were found in the classpath: ... /Users/2bab/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.4.31/84ce8e85f6e84270b2b501d44e9f0ba6ff64fa71/kotlin-stdlib-jdk7-1.4.31.jar (version 1.4) /Users/2bab/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.5.21/2f537cad7e9eeb9da73738c8812e1e4cf9b62e4e/kotlin-stdlib-1.5.21.jar (version 1.5) /Users/2bab/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.21/cc8bf3586fd2ebcf234058b9440bb406e62dfacb/kotlin-stdlib-common-1.5.21.jar (version 1.5) w: Consider providing an explicit dependency on kotlin-reflect 1.5 to prevent strange errors w: Some runtime JAR files in the classpath have an incompatible version. Consider removing them from the
用一个简单的例子看下问题是怎么发生的:
plugins {
id("com.android.application")
// 没有指定版本,用的就是 Gradle bundle 的版本,
// Gradle 7.1.1 对应的就是 Kotlin 1.4.31 的各种类库和编译工具
kotlin("android")
}
dependencies {
// 而这里我们却用了 1.5.21 的最新版 Kotlin,就会出现如上问题
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.5.21")
}
解决起来也很简单:
plugins {
id("com.android.application")
// 手动指定版本
kotlin("android") version "1.5.21"
}
Kotlin 官方的文档直接就演示了加版本号的写法。但是,这个版本是 Kotlin 基于 Gradle 测试通过,而 Gradle 自身还没有基于它测试过并打包进去(见 Gradle 部分的配图),若出现了问题可能难以解决:
所以我推荐的升级策略是:
前面提到 Kotlin 的官方文档解释了各类和 Gradle 配合兼容的情况,反过来 Gradle 这边也有一个标明了 Java 、Kotlin 、Android 等各语言和平台的支持文档。
像前面提到的 Java 版本支持,Kotlin 版本支持在这里便一目了然。除了 Kotlin 的支持会稍落后一两个月,其他工具的最新版本兼容都不成问题。而 Gradle 自身的向下兼容我觉得还不错,我基本上每个版本都升级。而上层的 AGP DSL,特别是老版本,则挺经常有大改动(好在 7.0 后终于强多了)。
所以我推荐的升级策略是:
另外,Gradle 7.0 后的版本原生支持了 M1,我个人的使用体验还不错。
AGP 的版本搭配限制我们在前面基本都介绍完了,以 7.0 为例,我们来看官方 Release Note 的兼容说明:
额外补充一点:从 AGP 7.0 起,其版本会同步 Gradle 的 major 版本,严格遵守 Semantic Versioning 体系(之前同步的是 AS 的版本)。也即 AGP 7.x 会适配 Gradle 7.x 的版本。不过 AGP 的发布时间依旧是随着 AS 一起发布,并且目前来看其 alpha/beta 的数字是跟随 AS 的,所以其实可以当成三者形成了某种默契的同步机制。
所以我推荐的升级策略是:
AS 基本上没有什么搭配限制,只要你用的之前正式版的 AGP,AS 就可以向下兼容。我推荐的升级策略是:
另外,由于 AS 基于的 IDEA 社区版二次开发,整体稳定性、新特性支持的速度都不如 IDEA Ultimate,例如 Gradle 的 nesting Composite Build 目前就不在 AS 支持范围,见该 issue。
最后,自 Arctic Fox 2020.3.1 起,AS 原生支持了 M1,但如果想有更流畅的体验,我认为 BumbleBee 2021.1.1 Canary 效果更好一些。
IDEA 的主要搭配限制来自于 Android Plugin ( Android IDE 插件)的版本适配。一般来说,在 AS 新的正式版本发布之后,下一个 IDEA 的正式版本就会带上该新版插件,从而对 Android 开发包括 AGP 做支持。
偶尔也有等比较久的时候,比如今年 AS&AGP 4.2 在 4 月发布,而直到 7 月 IDEA 2021.2 发布时,才更新了 Android Plugin,官方的说法是 Google 放出 AGP 4.2 的源码时间晚了些,导致没赶上 2021.1 的版本。
我推荐的升级策略是:
最后,2021.2 也是让我在 M1 感觉终于不再有什么卡顿的版本了。
我自己由于使用 M1 的平台 + 适配一些 Gradle Plugin,经常会使用 beta 甚至 alpha 的 AGP (作为 Runtime 的 library ),配合最新的 IDEA Ultimate 开发起来还是挺顺手。
而公司项目,现阶段 x86 平台我觉得可以使用如下配置,ARM M1 则根据上文调整对应的工具版本:
(欢迎订阅“Android 高效开发”↑)
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.