Android ビルドの Java バージョン

ソースコードの記述方法(Java、Kotlin、またはその両方)にかかわらず、ビルド用に JDK または Java 言語のバージョンを選択する必要がある場所がいくつかあります。

Gradle ビルドにおける JDK の関係の概要

用語集

Java Development Kit(JDK)
Java 開発キット(JDK)には、次のものが含まれます。
  • コンパイラ、プロファイラ、アーカイブ作成ツールなどのツール これらは、ビルド時にアプリケーションを作成するためにバックグラウンドで使用されます。
  • Kotlin または Java のソースコードから呼び出せる API を含むライブラリ。なお、Android ではすべての関数が使用できるわけではありません。
  • Java 仮想マシン(JVM)。Java アプリケーションを実行するインタープリタです。Android Studio IDE と Gradle ビルドツールの実行には、JVM を使用します。JVM は、Android デバイスやエミュレータでは使用されません。
JetBrains ランタイム(JBR)
JetBrains ランタイム(JBR) は拡張 JDK であり、Android Studio で配布されています。Studio や関連する JetBrains プロダクトで使用する最適化がいくつか含まれていますが、他の Java アプリケーションの実行にも使用できます。

Android Studio を実行する JDK を選択するにはどうすればよいですか?

JBR を使用して Android Studio を実行することをおすすめします。Android Studio でデプロイしてテストに使用します。また、Android Studio を最適に使用するための拡張機能も組み込まれています。そのためには、STUDIO_JDK 環境変数を設定しないでください。

Android Studio の起動スクリプトは、次の順序で JVM を検索します。

  1. STUDIO_JDK 環境変数
  2. studio.jdk ディレクトリ(Android Studio ディストリビューション内)
  3. Android Studio ディストリビューション内の jbr ディレクトリ(JetBrains Runtime)。おすすめ
  4. JDK_HOME 環境変数
  5. JAVA_HOME 環境変数
  6. PATH 環境変数内の java 実行可能ファイル

Gradle ビルドを実行する JDK を選択するにはどうすればよいですか?

Android Studio のボタンを使用して Gradle を実行すると、Android Studio の設定で設定された JDK を使用して Gradle が実行されます。Android Studio の内部または外部のターミナルで Gradle を実行する場合、JAVA_HOME 環境変数(設定されている場合)によって、Gradle スクリプトを実行する JDK が決まります。JAVA_HOME が設定されていない場合、PATH 環境変数で java コマンドが使用されます。

最も一貫した結果を得るには、JAVA_HOME 環境変数と、Android Studio の Gradle JDK 構成を同じ JDK に設定してください。

Gradle はビルドの実行時に、デーモンと呼ばれるプロセスを作成して実際のビルドを実行します。ビルドが同じ JDK と Gradle バージョンを使用している限り、このプロセスは再利用できます。デーモンを再利用すると、新しい 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_HOMEGRADLE_LOCAL_JAVA_HOME などのマクロ
  • Android 構成ファイルに保存されている、jbr-17 などの vendor-version 形式の JDK テーブル エントリ
  • JDK のダウンロード
  • 特定の JDK の追加
  • オペレーティング システムのデフォルト JDK インストール ディレクトリからローカルで検出された JDK

選択したオプションは、プロジェクトの .idea/gradle.xml ファイルの gradleJvm オプションに格納されます。その JDK パス解決を使用して、Android Studio からの起動時に Gradle を実行します。

図 1. Android Studio での Gradle JDK 設定。

このマクロを使用すると、プロジェクト JDK パスの動的な選択が可能になります。

  • JAVA_HOME: 同じ名前の環境変数を使用します。
  • GRADLE_LOCAL_JAVA_HOME: .gradle/config.properties ファイルの java.home プロパティを使用します。デフォルトは JetBrains ランタイムです。

選択した JDK は、Gradle ビルドの実行と、ビルド スクリプトとソースコードの編集時に JDK API 参照の解決に使用されます。指定した compileSdk により、ソースコードの編集とビルド時に使用できる Java シンボルがさらに制限されます。

Gradle ビルドで使用するプラグインで使用される JDK バージョン以上の 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/jdk11
      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 の一部を使用できますが、すべてではありません。Android SDK では、利用可能な API の一部として、さまざまな Java ライブラリ関数の実装が定義されています。compileSdk プロパティは、Kotlin または Java のソースコードをコンパイルするときに使用する Android SDK バージョンを指定します。

Kotlin

android {
    ...
    compileSdk = 33
}

Groovy

android {
    ...
    compileSdk 33
}

Android の各バージョンは、特定のバージョンの JDK と利用可能な Java API のサブセットをサポートしています。使用している compileSdk で利用可能な Java API が、指定された minSdk では利用できない場合、脱糖と呼ばれるプロセスにより、以前のバージョンの 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 のバージョン

Java ソースコードをコンパイルする JDK を教えてください。

Java ツールチェーン JDK には、Java ソースコードのコンパイルに使用される Java コンパイラが含まれています。この JDK は、ビルド中に javadoc と単体テストも実行します。

ツールチェーンのデフォルトは、Gradle の実行に使用される JDK です。デフォルトを使用して、異なるマシン(ローカルマシンと個別の継続的インテグレーション サーバーなど)でビルドを実行する場合、使用する JDK バージョンが異なるとビルドの結果が異なることがあります。

より一貫したビルドを作成するには、Java ツールチェーンのバージョンを明示的に指定します。次のように指定します。

  • ビルドを実行しているシステム上で互換性のある JDK を探します。
    • 互換性のある JDK が存在しない場合(かつツールチェーン リゾルバが定義されている場合)は、JDK をダウンロードします。
  • ソースコードからの呼び出し用にツールチェーン Java API を公開します。
  • Java 言語バージョンを使用して Java ソースをコンパイルします。
  • sourceCompatibilitytargetCompatibility のデフォルトを提供します。

常に Java ツールチェーンを指定して、指定した JDK がインストールされていることを確認するか、ビルドにツールチェーン リゾルバを追加することをおすすめします。

ソースコードの記述方法(Java、Kotlin、またはその両方)は、ツールチェーンを指定できます。ツールチェーンは、モジュールの build.gradle(.kts) ファイルの最上位に指定します。

ソースコードが Java のみで記述されている場合は、Java ツールチェーンのバージョンを次のように指定します。

Kotlin

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

Groovy

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

ソースが Kotlin のみの場合、または Kotlin と Java が混在している場合は、Java ツールチェーンのバージョンを次のように指定します。

Kotlin

kotlin {
    jvmToolchain(17)
}

Groovy

kotlin {
    jvmToolchain 17
}

ツールチェーン JDK のバージョンは、Gradle の実行に使用する JDK と同じにできますが、目的は異なることに注意してください。

Java ソースコードではどの Java 言語ソース機能を使用できますか?

sourceCompatibility プロパティにより、Java ソースのコンパイル中に使用できる Java 言語機能が決まります。Kotlin ソースには影響しません。

指定しない場合、Gradle の実行に使用される Java ツールチェーンまたは JDK がデフォルトになります。常にツールチェーン(推奨)または sourceCompatibility を明示的に指定することをおすすめします。

モジュールの build.gradle(.kts) ファイルで sourceCompatibility を指定します。

Kotlin

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
    }
}

Groovy

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
    }
}

Kotlin または Java ソースをコンパイルするときに使用できる Java バイナリ機能はどれですか?

targetCompatibilityjvmTarget を指定すると、コンパイル済みの Java ソースと Kotlin ソースのバイトコードを生成するときに使用される Java クラス形式のバージョンが、それぞれ決定されます。

Kotlin の一部の機能は、同等の Java 機能が追加される前から存在していました。初期の Kotlin コンパイラは、こうした Kotlin 機能を表現するための独自の方法を作成する必要がありました。これらの機能の一部は後で Java に追加されました。それ以降の jvmTarget レベルでは、Kotlin コンパイラが Java 機能を直接使用することになり、パフォーマンスが向上する可能性があります。

targetCompatibility のデフォルトは sourceCompatibility と同じ値ですが、指定する場合は sourceCompatibility 以上にする必要があります。

jvmTarget のデフォルトは、ツールチェーンのバージョンです。

Android のバージョンが異なれば、サポートされる Java のバージョンも異なります。targetCompatibilityjvmTarget の値を増やすと、追加の Java 機能を利用できますが、この機能を確実に利用するには Android SDK の最小バージョンの引き上げも必要になる場合があります。

Kotlin

android {
    compileOptions {
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

Groovy

android {
    compileOptions {
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget '17'
    }
}