作为一个 Android 开发,走出第一步往往是很困难的,因为要面对巨杂乱的环境装备问题,一个是 gradle 与 AGP 之间纠缠不清的关系,另一个便是 java 版别相关的各种装备。今天咱们就回归基础,一起整理下 java 版别相关的各种装备是为了什么。

基础知识

咱们知道,Java/Kotlin 言语需求由源代码(.java / .kt 文件)编译成字节码存放在 .class 文件中。Android 还会打包成 dex 文件,最终运转在虚拟机上。

Java 言语在不断发展,每个新版别都会引进新的言语特性和语法,以便开发者编写功用更强大的程序。这些新增的言语特性都只存在于源代码中,被称为 Java 言语源代码特性。例如,Java 8 增加了 lambda 表达式。

class 文件包含了 Java 程序运转时的二进制信息,如数据类型、方法信息等。class 文件格局也是在不断演化的,其被称之为 java 二进制特性,与 java 言语源代码特性不同,Java 二进制特性的演进相对比较保守,通常多个 Java 版别会坚持相同的 class 文件格局。只要在重大言语特性修改时,才会引进新的class文件格局。所以 Java 言语版别和 class 文件格局版别不完全对应。

咱们装备时,就需求一起考虑 java 言源代码特性版别的装备和 java 二进制特性版别的装备

java 二进制特性版别的装备

与服务端不同的是,咱们的应用是跑在用户的手机上,用户可能用了低版别的 Android ,那么其 jvm 环境也便是低版别了。所以咱们需求将咱们的代码编译成低版别 jvm 环境也能运转的字节码。

如果是 java, 那么能够经过 targetCompatibility 来装备:

compileOptions {
    targetCompatibility = JavaVersion.VERSION_11
} 

如果是 kotlin,则经过 jvmTarget 来装备

kotlinOptions {
    jvmTarget = "11"
}

现在咱们设置方针为 java 11, 那么如果咱们用户的手机体系低于 Android 10, 不支持 java 11,为何也能够正常作业呢?

这就要提到 desugaring 技术(google/desugar_jdk_libs)了,它能够将高版别的语法糖转化为低版别的完成,其完成是从字节码层面做转化。

那为什么咱们不将方针版别设置得更低,而是要用 desugaring 技术呢?

因为这个 desugaring 技术能够经过 if/else 之类的手法判断 Android 版别,低版别才走 desugaring 转化后的完成,高版别坚持运用高档特性,从而享用高档特性带来的性能提升。

那为什么要设置为 java 11 呢?

那是因为现在 desugar_jdk_libs 就只支持到了 java 11,所以现在主流的 Android 项目现在最高也只能设置到 java 11

Java 言语源代码特性版别的装备

咱们回到 Android 的编译上,Android 运用 gradle 进行编译,而 gradle 也是跑在 java 环境的,它也是要求 java 环境的,例如最新的 8.x 系列是跑在 jdk 17 上,咱们能够在 Android Studio > Setting > Build Tool > gradle 中装备。

因为 java 新版别总会出各种新的特性,所以咱们不能用 jdk 17 去编译出 java 11 的字节码,即使编译得通,也容易出翔。在 gradle 旧版别,gradle 所运转的 jdk 环境与编译源码的 jdk 耦合比较严峻,所以装备会出现彼此影响与彼此束缚的情况。

gradle 7.4 出了 javaToolChain 的东西,它能够让咱们装备编译源代码采用独自的 jdk

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(11))
    }
}

如果运用了 kotlin,则装备:

kotlin {
    jvmToolchain(11)
}

当然,kotlin 要求版别至少为 1.5.30

Android 还能够设置 sourceCompatibility,其指明源码运用的 java 版别,有了 toolchain 后,它主要给 Android Studio 用,用于 lint 提示咱们不要写出高版别的语法糖。

其实咱们能够发现,toolchain 出来后,就能够把咱们从 gradle 运转、java 源代码编译、kotlin 源代码编译采用 jdk 的严峻耦合中解放出来,装备更灵活了,当然装备项也更多了,也有一定的了解成本,我们也需求理解各自的用途才能玩得很顺。

最后

gradle 虽然仍是很慢,可是也不断有许多很好的改善点,早升级早享用。现在咱们还能够将一切的装备项抽取出来,运用 Composing builds 管理,具体能够参阅官方的 Now in Android 项目或许我的 emo 项目的 build-logic


我是古哥E下,前微信读书客户端程序猿 / 自学 5 年中医,保护过上万 Star 开源项目 QMUI Android,现独立保护好用简练的 Android 组件库 emo

关注我可得:ChatGPT 开发玩法 | 程序员学习经历 | 组件库新变动 | 中医健康调度 。

emo官网:emo.qhplus.cn