使用 Java 8 語言功能和 API

Android Gradle 外掛程式 3.0.0 以上版本支援所有 Java 7 語言功能,以及部分 Java 8 語言功能 (視平台版本而定)。透過 Android Gradle 外掛程式 4.0.0 以上版本建構應用程式時,您不必為應用程式設定最低 API 級別,就能使用部分 Java 8 語言 API。

本頁將說明可使用的 Java 8 語言功能、如何正確設定專案來使用這些功能,以及可能遇到的已知問題。如需 Java 8 語言功能簡介,請觀看以下影片。

針對特定 Java 8 語言功能,以及採用這些功能的第三方程式庫,Android Gradle 外掛程式提供了內建支援。如圖 1 所示,預設的工具鏈會以 D8/R8 將類別檔案編譯為 DEX 程式碼,在這個過程中執行名為 desugar 的位元碼轉換作業,實作新的語言功能。

透過「脫糖」位元碼轉換作業支援 Java 8 語言功能
圖 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 以上版本也將 try-with-resources 的支援範圍擴及所有 Android API 級別。

脫糖程序並不支援 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+ 語言功能的脫糖程序不會提供任何額外類別和 API (例如 java.util.stream.*) 給舊版 Android 使用。請注意,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 的應用程式中,加入原本只能在近期 Android 版本中使用的標準語言 API,例如 java.util.streams

使用 Android Gradle 外掛程式 4.0.0 以上版本建構應用程式時,系統會支援下列 API:

  • 依序串流 (java.util.stream)
  • java.time 的子集
  • java.util.function
  • java.util.{Map,Collection,Comparator} 的近期新增內容
  • Optional (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 的實作項目,並將其納入應用程式。這個脫糖程序會重新編寫應用程式的程式碼,並在執行階段改為使用這個程式庫。編譯成獨立 DEX 檔案的原始碼可在 desugar_jdk_libs GitHub 存放區中找到。

如要在任何版本的 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 的有效用量,並避免誤報警示。

另請注意,只有在使用 R8 縮減器時,API 脫糖作業可以與縮減作業合併進行。

版本

下表列出 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 檔案