使用 Java 8 语言特性和 API

Android Gradle 插件 3.0.0 及更高版本支持所有 Java 7 语言特性以及平台版本各异的 Java 8 语言特性的子集。当使用 Android Gradle 插件 4.0.0 及更高版本构建应用时,您可以使用一些 Java 8 语言 API,而无需为应用指定最低 API 级别。

此页面介绍了您可以使用的 Java 8 语言特性、如何正确配置项目以使用它们以及可能遇到的任何已知问题。请参阅以下视频,了解 Java 8 语言特性的概述。

Android Gradle 插件提供了对使用某些 Java 8 语言特性以及使用它们的第三方库的内置支持。默认工具链通过执行字节码转换(称为desugar)来实现新的语言特性,作为将类文件编译成 DEX 代码的 D8/R8 编译的一部分,如图 1 所示。

Java 8 language feature support using `desugar` bytecode
    transformations
图 1. 使用desugar 字节码转换支持 Java 8 语言特性。

Java 8 语言特性支持(Android Gradle 插件 3.0.0 及更高版本)

要开始使用受支持的 Java 8 语言特性

  1. 将 Android Gradle 插件更新到 3.0.0 或更高版本。
  2. 对于每个使用 Java 8 语言特性(在其源代码中或通过依赖项)的模块,请更新模块的build.gradlebuild.gradle.kts文件,如下所示

Kotlin

android {
    ...
    // Configure only for each module that uses Java 8
    // language features (either in its source code or
    // through dependencies).
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

Groovy

android {
    ...
    // Configure only for each module that uses Java 8
    // language features (either in its source code or
    // through dependencies).
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

当使用 Android Gradle 插件 3.0.0 及更高版本构建应用时,插件不支持所有 Java 8 语言特性。以下语言特性在任何 API 级别上都可用

Java 8 语言特性 说明
Lambda 表达式 Android 不支持 Lambda 表达式的序列化。
方法引用  
类型注释 类型注释信息仅在编译时可用,在运行时不可用。平台在 API 级别 24 及以下版本支持TYPE,但不支持ElementType.TYPE_USEElementType.TYPE_PARAMETER
默认和静态接口方法  
重复注释  

除了这些 Java 8 语言特性之外,Android Gradle 插件版本 3.0.0 及更高版本还将对所有 Android API 级别扩展 try-with-resources的支持。

Desugar 不支持MethodHandle.invokeMethodHandle.invokeExact。如果您的源代码或您的某个模块依赖项使用了其中一种方法,则需要指定minSdkVersion 26或更高版本。否则,您将收到以下错误

Dex: Error converting bytecode to dex:
Cause: signature-polymorphic method called without --min-sdk-version >= 26

在某些情况下,即使您的模块依赖项中包含invokeinvokeExact方法,您的模块也可能未使用它们。要继续使用minSdkVersion 25或更低版本的库,请启用代码压缩以删除未使用的代码。如果这不起作用,请考虑使用不使用不受支持方法的备用库。

Android Gradle 插件 3.0.0 及更高版本上的 Java 8+ 语言特性去糖化不会为旧版 Android 版本提供任何其他类和 API(例如java.util.stream.*)。Android Gradle 插件 4.0.0 或更高版本提供了对部分 Java API 去糖化的支持,如下节所述。

Java 8+ API 去糖化支持(Android Gradle 插件 4.0.0 及更高版本)

如果您使用 Android Gradle 插件 4.0.0 或更高版本构建应用,则插件扩展了对使用许多 Java 8 语言 API 的支持,而无需为应用指定最低 API 级别。使用 Android Gradle 插件 7.4.0 或更高版本,还可以使用一些 Java 11 语言 API,这些 API 使用去糖化的库 2.0.0 或更高版本。

对旧版平台版本的这种额外支持之所以成为可能,是因为插件 4.0.0 及更高版本扩展了去糖化引擎,使其还可以去糖化 Java 语言 API。您可以在支持旧版 Android 版本的应用中包含仅在最新 Android 版本中可用的标准语言 API(例如java.util.streams)。

使用 Android Gradle 插件 4.0.0 或更高版本构建应用时,支持以下 API 集

  • 顺序流 (java.util.stream)
  • java.time 的子集
  • java.util.function
  • java.util.{Map,Collection,Comparator} 的最新新增功能
  • 可选 (java.util.Optionaljava.util.OptionalIntjava.util.OptionalDouble) 和一些新类
  • java.util.concurrent.atomic 中的一些新增功能(AtomicIntegerAtomicLongAtomicReference 上的新方法)
  • ConcurrentHashMap(修复了 Android 5.0 中的错误)

使用 Android Gradle 插件 7.4.0 或更高版本,还支持其他 Java 11 API,例如 java.nio.file 包的子集。

有关受支持 API 的完整列表,请访问通过去糖化提供的 Java 8+ API通过去糖化提供的 Java 11+ API

为了支持这些语言 API,插件会编译一个包含缺失 API 实现的单独 DEX 文件,并将其包含在您的应用中。去糖化过程会重写应用的代码,以便在运行时使用此库。

要在任何版本的 Android 平台上启用对这些语言 API 的支持

  1. 将 Android Gradle 插件更新到 4.0.0(或更高版本)。
  2. 在您的应用模块build.gradlebuild.gradle.kts文件中包含以下内容

Kotlin

android {
    defaultConfig {
        // Required when setting minSdkVersion to 20 or lower
        multiDexEnabled = true
    }

    compileOptions {
        // Flag to enable support for the new language APIs

        // For AGP 4.1+
        isCoreLibraryDesugaringEnabled = true
        // For AGP 4.0
        // coreLibraryDesugaringEnabled = true

        // Sets Java compatibility to Java 8
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
}

dependencies {
    // For AGP 7.4+
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3")
    // For AGP 7.3
    // coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.3")
    // For AGP 4.0 to 7.2
    // coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.9")
}

Groovy

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 {
    // For AGP 7.4+
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'
    // For AGP 7.3
    // coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.3'
    // For AGP 4.0 to 7.2
    // coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.9'
}

请注意,如果以下情况,您可能还需要在库模块的build.gradlebuild.gradle.kts文件中包含前面的代码片段:

  • 库模块的已插入测试使用这些语言 API(直接或通过库模块或其依赖项)。这样是为了为您的已插入测试 APK 提供缺失的 API。

  • 您希望单独对库模块运行 lint。这样可以帮助 lint 识别语言 API 的有效用法,并避免报告错误警告。

另请注意,API 去糖化可以与压缩结合使用,但仅当使用 R8 压缩器时。

版本

下表显示了 Java 8+ API 库的版本以及支持每个版本的最低 Android Gradle 插件版本

版本 最低 Android Gradle 插件版本
1.1.9 4.0.0
1.2.3 7.3.0
2.0.3 7.4.0-alpha10

有关 Java 8+ API 库版本的详细信息,请参阅desugar_jdk_libs GitHub 存储库中的CHANGELOG.md 文件