使用 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 的情況下使用許多 Java 8 語言 API 應用程式必須設定最低 API 級別。使用 Android Gradle 外掛程式 7.4.0 或 許多 Java 11 語言 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} 的近期新增內容
  • 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 的實作項目),並將這個檔案加入應用程式中。脫糖程序會重新編寫應用程式的程式碼,在執行階段改為使用此程式庫。

如要在任何版本的 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 檔案