本文目标

很多时分业务开发者想用一些比较快捷的api完成功用, 发现要改工程装备, 而假如对工程装备的概念不理解,很可能会牵一发起全身.

本文便是对装备AGP中触及的Java版别做了一下收拾, 便是单纯的厘清概念, 没有深邃的源码剖析. 因为没有自己的干货,满是网络搜索的结果, 所以外链会比较多.

compileSdkVersion

每次晋级compileSdkVersion, 咱们都会下载相应的android SDK, 取得相应的android 特性开发才能, 这里边也包括对应的Java SDK, 也便是说咱们能运用什么Java Api 是由compileSdkVersion 对应的Java 版别决定的, 和咱们电脑本地的Java SDK版别不要紧

android AGP配置对Java版本支持的梳理

究竟假如咱们想要在android 6上运用Java 19的特性, 也要android 6支撑才能够.

By default, the Java language version used to compile your project is based on your project’scompileSdkVersion

依据Android各版别对应的SDK及JDK版别要求 咱们能够看到在android12上咱们能够运用JDK11进行开发, 而在即将发布的android14,咱们能够运用JDK17.

Gradle

适用于android和Java 工程的构建东西, 依据JVM. 构建是在咱们电脑上或许远程服务器构建, 而不是用户的手机上,所以需求在构建机器上具备JDK环境. 而Android Studio会内置JDK,所以咱们就选择内置JDK就好, 假如有需求能够选择咱们电脑上已安装的其他版别JDK.

android AGP配置对Java版本支持的梳理

不同版别的Gradle对JDK有不同要求, 比方Gradle7.0曾经要求是JDK1.8, 7.X版别要求是JDK11, 8.X版别则是要求JDK17.

AGP

Android Gradle Plugin(简称AGP) 是用于在Android Studio中对项目工程代码构建的插件. 其作用是在咱们项目代码和Gradle之间架起一座桥梁, 方便咱们在Android Studio中直接构建, 而不需求凭借指令行或其他东西. 既然是起到桥梁作用,那就需求和两头的Java的环境相匹配.

适配Gradle JDK版别

在AGP7.X之后的大版别都和Gradle大版别要求的JDK版别保持共同, 为JDK11, JDK17, 在AGP7.0之前则为JDK1.8

When using Android Gradle plugin 7.0 to build your app, JDK 11 is now required to run Gradle. Android Studio Arctic Fox bundles JDK 11 and configures Gradle to use it by default, which means that most Android Studio users do not need to make any configuration changes to their projects.

When using Android Gradle Plugin 8.0 to build your app, JDK 17 is now required to run Gradle. Android Studio Flamingo bundles JDK 17 and configures Gradle to use it by default, which means that most Android Studio users don’t need to make any configuration changes to their projects.

具体可拜见: developer.android.google.cn/build/relea…

developer.android.google.cn/build/relea…

需求留意的是,在咱们晋级Android Studio后, 假如当时AS还兼容工程装备的AGP版别, 那么AGP和Gradle不晋级也能够,不然就需求晋级. 开发者需求自行留意AS与AGP的兼容情况和相关api改动

适配项目工程 JDK版别

AGP 默许构建JDK 版别

首先说一下,AGP其实是有自己默许的构建JDK版别的, 即不管咱们用指定什么JDK版别开发(compileSdkVersion), AGP都会用它默许的JDK版别编译.在AGP4.2.0曾经的版别, AGP采用Java1.7编译,而在AGP4.2.0之后的版别采用的是Java1.8编译

AGP4.2.0 release notes

Starting in version 4.2, AGP will use the Java 8 language level by default.

那么问题来了, 用一个JDK版别开发,用另一个JDK编译, 那么编译肯定会出问题, 咱们开发者岂不是要等到编译时才会留意到出现了 JDK版别问题? 那IDE给出的解决方案是采用lint.

不同版别的Android Studio对应不同版别AGP, 也一起对应着不同的lint规矩. 这样当咱们用不同的compileSdkVersion开发时, lint东西就会发现咱们开发运用的JDK Api与编译JDK Api的不同, 并给出警告或许错误.

android AGP配置对Java版本支持的梳理
可是假如一向要保持与编译JDK版别共同,不是意味着咱们只能一向运用JDK1.8或许JDK1.7的特性?

AGP 适配构建JDK 版别

// build.gradle
android {
 ...
 compileOptions {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
 }
 
}

经过上述装备,咱们能够更改AGP的构建版别为指定的JDK版别, 留意,只要需求的编译版别和默许版别不共同就需求这样处理, 不管咱们需求的是JDK1.8,仍是JDK11, JDK17, 当然最高的JDK版别约束仍是compileSdkVersion的JDK版别.

android AGP配置对Java版本支持的梳理

而这个适配装备和上面的Gradle JDK版别没有关系, 即使Gradle已经要求了JDK 17, 这里咱们仍然能够运用JDK1.8版别进行编译.

而这个适配装备的更改实际上便是在编译履行javac指令时,装备的参数,比方:

path/to/jdk9/bin/javac Compile8Test.java -source 8 -target 8

假如没有-source选项,编译器将依据所运用的 Java 版别运用源代码进行编译。

target 选项指定要生成的类文件的 Java 版别。target版别有必要等于或高于source版别

参阅A Guide to Java Source and Target Options

docs.oracle.com/javase/8/do…

验证

  1. 随便运用某个版别的AS创建一个android示例工程,能够采用最新版别
  2. 在相关装备都同步好,能够运转时,clean工程,再次build
  3. 在app/build/intermediates/javac/debug/classes/包名文件夹下能够找到刚才编译的MainActivity.class字节码文件
  4. 把这个字节码文件路径复制下,或许文件挪到其他方位, 在终端运转:
javap -v 文件夹路径/MainActivity.class

能够看到终端输出很多东西, 而在其中就有编译所运用的JDK 版别:

android AGP配置对Java版本支持的梳理

version55对应Java11 (参阅维基) , 之后能够删去/更改适配装备, 再次clean,build 检查版别改变

Kotlin的JVM版别

Kotlin在1.5版别曾经仍是JDK1.6但在1.5版别之后便是1.8, 咱们也能够同样在APG中进行装备, 只不过装备Kotlin的一起需求装备相同版别的Java:

android {
 ...
 compileOptions {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
 }
 kotlinOptions {
  jvmTarget = "1.8"
 }
}

官方也供给了AGP对Kotlin的兼容版别说明:

D8 and R8 compiler versions required for Kotlin versions

低版别系统适配:D8

咱们用了JDK11, 17开发, android高版别系统支撑, 可是低版别系统呢? 怎么处理这些新特性呢, 答案便是脱糖

d8经过一个叫做“脱糖”的编译过程,使您能够在代码中运用 Java 8 言语功用。脱糖会将这些实用的言语功用转换为能够在 Android 平台上运转的字节码。 Android Studio 和 Android Gradle 插件包括了d8为您启用脱糖所需的类路径资源。

D8更多细节

在Androd Studio 3.0.0版别就开始支撑了D8, 不过3.X版别仅仅支撑Java8, 而假如想运用更高版别JDK Api并运转在低版别系统上, 则需求运用Android Studio 4.X以上版别, 一起为了运用愈加广泛的支撑脱糖的Api, 咱们能够在APG里装备:

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }
  compileOptions {
    // Flag to enable support for the new language APIs
    coreLibraryDesugaringEnabled true
    // Sets Java compatibility to Java 8
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}
dependencies {
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'
}

具体可拜见:

语法糖、脱糖、D8

library desugaring

java8 support table

java11 minimal support table

Android 的 Java 9、10、11 和 12 支撑

AGP Java Support

本文参阅

Android 和 Java 的那些事

Android gradle 中为什么要添加 java8 兼容装备?