無論原始碼是使用 Java、Kotlin 或兩者編寫,您都必須在幾個地方為建構作業選擇 JDK 或 Java 語言版本。
詞彙解釋
- Java Development Kit (JDK)
-
Java Development Kit (JDK) 包含:
- 工具,例如編譯器、分析器和封存檔建立工具。這些檔案會在建構期間在幕後使用,用於建立應用程式。
- 包含可從 Kotlin 或 Java 來源程式碼呼叫的 API 的程式庫。請注意,Android 不支援所有函式。
- Java 虛擬機器 (JVM),這是執行 Java 應用程式的轉譯器。您可以使用 JVM 執行 Android Studio IDE 和 Gradle 建構工具。JVM 不會用於 Android 裝置或模擬器。
- JetBrains 執行階段 (JBR)
- JetBrains Runtime (JBR) 是一種強化的 JDK,會隨 Android Studio 發布。其中包含多項最佳化功能,可用於 Studio 和相關的 JetBrains 產品,但也可以用於執行其他 Java 應用程式。
如何選擇 JDK 來執行 Android Studio?
建議您使用 JBR 執行 Android Studio。此工具會與 Android Studio 一併部署,用於測試 Android Studio,並提供最佳 Android Studio 使用方式的強化功能。為確保這項功能正常運作,請勿設定 STUDIO_JDK
環境變數。
Android Studio 的啟動指令碼會依照以下順序尋找 JVM:
STUDIO_JDK
環境變數studio.jdk
目錄 (在 Android Studio 發行版本中)jbr
目錄 (JetBrains Runtime) 中的 Android Studio 發布版本。推薦影片。JDK_HOME
環境變數JAVA_HOME
環境變數java
可執行檔 (位於PATH
環境變數中)
如何選擇執行 Gradle 建構作業的 JDK?
如果您使用 Android Studio 中的按鈕執行 Gradle,系統會使用 Android Studio 設定中設定的 JDK 來執行 Gradle。如果您在終端機中執行 Gradle (無論是在 Android Studio 內或外),JAVA_HOME
環境變數 (如果已設定) 會決定 Gradle 指令碼會在哪個 JDK 上執行。如果未設定 JAVA_HOME
,系統會在 PATH
環境變數上使用 java
指令。
為獲得最一致的結果,請務必將 JAVA_HOME
環境變數和 Android Studio 中的 Gradle JDK 設定設為相同的 JDK。
執行建構作業時,Gradle 會建立稱為「Daemon」的程序,以便執行實際建構作業。只要建構作業使用相同的 JDK 和 Gradle 版本,即可重複使用此程序。重複使用 Daemon 可縮短啟動新 JVM 和初始化建構系統的時間。
如果您使用不同的 JDK 或 Gradle 版本啟動建構作業,系統會建立額外的守護程序,進而消耗更多 CPU 和記憶體。
Android Studio 中的 Gradle JDK 設定
如要修改現有專案的 Gradle JDK 設定,請依序點選「File」 (或 macOS 上的「Android Studio」) >「Settings」>「Build, Execution, Deployment」>「Build Tools」>「Gradle」,開啟 Gradle 設定。「Gradle JDK」下拉式選單包含下列選項:
- 巨集,例如
JAVA_HOME
和GRADLE_LOCAL_JAVA_HOME
- 以
vendor-version
格式 (例如jbr-17
) 儲存在 Android 設定檔中的 JDK 表格項目 - 下載 JDK
- 新增特定 JDK
- 從作業系統的預設 JDK 安裝目錄偵測到的本機 JDK
所選選項會儲存在專案 .idea/gradle.xml
檔案的 gradleJvm
選項中,其 JDK 路徑解析結果會用於透過 Android Studio 啟動 Gradle 時執行。
巨集可啟用動態專案 JDK 路徑選取功能:
JAVA_HOME
:使用同名的環境變數GRADLE_LOCAL_JAVA_HOME
:使用.gradle/config.properties
檔案中的java.home
屬性,預設為 JetBrains 執行階段。
系統會在編輯建構指令碼和原始碼時,使用所選 JDK 執行 Gradle 建構作業,並解析 JDK API 參照。請注意,指定的 compileSdk
會進一步限制編輯及建構原始碼時可用的 Java 符號。
請務必選擇的 JDK 版本高於或等於 Gradle 建構中所用外掛程式使用的 JDK 版本。如要判斷 Android Gradle 外掛程式 (AGP) 所需的最低 JDK 版本,請參閱版本資訊中的相容性表格。
舉例來說,Android Gradle 外掛程式 8.x 版需要 JDK 17。如果您嘗試執行使用舊版 JDK 的 Gradle 建構作業,系統會回報類似以下的訊息:
An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
> Android Gradle plugin requires Java 17 to run. You are currently using Java 11.
Your current JDK is located in /usr/local/buildtools/java/jdk
You can try some of the following options:
- changing the IDE settings.
- changing the JAVA_HOME environment variable.
- changing `org.gradle.java.home` in `gradle.properties`.
我在 Java 或 Kotlin 原始碼中可以使用哪些 Java API?
Android 應用程式可以使用 JDK 中定義的部分 API,但無法使用所有 API。Android SDK 會將許多 Java 程式庫函式的實作方式定義為可用 API 的一部分。compileSdk
屬性會指定編譯 Kotlin 或 Java 原始碼時要使用的 Android SDK 版本。
Kotlin
android {
...
compileSdk = 33
}
Groovy
android {
...
compileSdk 33
}
每個 Android 版本都支援特定版本的 JDK,以及其可用的 Java API 子集。如果您使用的是 compileSdk
中提供的 Java API,但該 API 無法在指定的 minSdk
中使用,您或許可以透過稱為「desugaring」的程序,在舊版 Android 中使用該 API。如要瞭解支援的 API,請參閱「可透過脫糖取得的 Java 11 以上版本 API」。
您可以使用這份表格判斷各 Android API 支援哪個 Java 版本,以及如何查看可用的 Java API 詳細資料。
Android | Java | 支援的 API 和語言功能 |
---|---|---|
14 (API 34) | 17 | 核心程式庫 |
13 (API 33) | 11 | 核心程式庫 |
12 (API 32) | 11 | Java API |
11 以下 | Android 版本 |
哪個 JDK 會編譯我的 Java 原始碼?
Java 工具鍊 JDK 包含用於編譯任何 Java 原始碼的 Java 編譯器。這個 JDK 也會在建構期間執行 Javadoc 和單元測試。
工具鍊預設為用於執行 Gradle 的 JDK。如果您使用預設值,並在不同機器上執行建構作業 (例如,本機機器和獨立的持續整合伺服器),如果使用不同版本的 JDK,建構結果可能會有所不同。
如要建立更一致的建構作業,您可以明確指定 Java 工具鍊版本。指定以下項目:
- 在執行建構作業的系統上找出相容的 JDK。
- 如果沒有相容的 JDK (且已定義工具鍊解析器),則下載一個。
- 公開工具鍊 Java API,供原始碼呼叫使用。
- 使用 Java 語言版本編譯 Java 來源。
- 為
sourceCompatibility
和targetCompatibility
提供預設值。
建議您一律指定 Java 工具鍊,並確保已安裝指定的 JDK,或在建構中新增工具鍊解析器。
無論原始碼是使用 Java、Kotlin 或兩者皆是,您都可以指定工具鍊。在模組的 build.gradle(.kts)
檔案頂層指定工具鍊。
請按照以下方式指定 Java 工具鍊版本:
Kotlin
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
Groovy
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
無論來源是 Kotlin、Java 或兩者皆是混合型,這項做法都適用。
工具鍊 JDK 版本可以與用於執行 Gradle 的 JDK 相同,但請注意,這兩者用途不同。
我可以在 Java 原始碼中使用哪些 Java 語言來源功能?
sourceCompatibility
屬性會決定在編譯 Java 來源時可用的 Java 語言功能。不會影響 Kotlin 來源。
在模組的 build.gradle(.kts)
檔案中指定 sourceCompatibility
,如下所示:
Kotlin
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
}
}
Groovy
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
}
}
如未指定,此屬性會預設為 Java 工具鍊版本。如果您未使用 Java 工具鍊,則預設會採用 Android Gradle 外掛程式所選的版本 (例如 Java 8 以上版本)。
編譯 Kotlin 或 Java 來源時,可以使用哪些 Java 二進位元功能?
targetCompatibility
和 jvmTarget
屬性會分別決定為編譯的 Java 和 Kotlin 來源產生位元碼時,所使用的 Java 類別格式版本。
某些 Kotlin 功能在相等的 Java 功能加入之前就已存在。早期的 Kotlin 編譯器必須自行建立方式,才能呈現這些 Kotlin 功能。其中部分功能後來已新增至 Java。在較新的 jvmTarget
級別中,Kotlin 編譯器可能會直接使用 Java 功能,進而提升效能。
不同的 Android 版本支援不同的 Java 版本。您可以透過增加 targetCompatibility
和 jvmTarget
來運用其他 Java 功能,但這可能會迫使您也提高Android SDK 最低版本,以確保該功能可供使用。
請注意,targetCompatibility
必須大於或等於 sourceCompatibility
。實際上,sourceCompatibility
、targetCompatibility
和 jvmTarget
通常應使用相同的值。您可以按照下列方式設定:
Kotlin
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
Groovy
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget '17'
}
}
如未指定,這些屬性會預設為 Java 工具鍊版本。如果您未使用 Java 工具鍊,則預設值可能會有所不同,並導致建構問題。因此,建議您一律明確指定這些值,或使用 Java 工具鍊。