使用 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 表达式的序列化。
方法引用  
类型注解 类型注解信息仅在编译时可用,在运行时不可用。该平台支持 TYPE 在 API 级别 24 及以下,但不支持 ElementType.TYPE_USEElementType.TYPE_PARAMETER
默认和静态接口方法  
重复注解  

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

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 或更高版本,还可以使用反糖化库 2.0.0 或更高版本使用一些 Java 11 语言 API。

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

使用 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,插件会编译一个单独的 DEX 文件,其中包含缺失 API 的实现,并将其包含在您的应用程序中。反糖化过程会重写您的应用程序代码,使其在运行时使用此库。

要在任何版本的 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 文件