Android ビルドの Java バージョン

ソースコードが Java、Kotlin、またはその両方で記述されている場合、ビルドの JDK または Java 言語のバージョンを選択する必要がある場所がいくつかあります。

Gradle ビルドでの JDK の関係の概要
図 1. ビルド内の JDK の関係

用語集

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

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

Android Studio の実行には、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 ランタイム)おすすめ
  4. JDK_HOME 環境変数
  5. JAVA_HOME 環境変数
  6. PATH 環境変数内の java 実行可能ファイル

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

Android Studio のボタンを使用して Gradle を実行する場合、Android Studio の設定で設定された JDK が Gradle の実行に使用されます。Android Studio の内部または外部のターミナルで Gradle を実行する場合、Gradle スクリプトを実行する JDK は JAVA_HOME 環境変数(設定されている場合)によって決まります。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 が実行されます。

図 2. Android Studio の Gradle JDK 設定

マクロを使用すると、動的プロジェクトの JDK パスを選択できます。

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

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

Kotlin

android {
    ...
    compileSdk = 33
}

Groovy

android {
    ...
    compileSdk 33
}

Android の各バージョンは、特定のバージョンの JDK と、使用可能な Java API のサブセットをサポートしています。指定された minSdk では使用できない compileSdk で使用可能な Java API を使用している場合は、デシュガーリングと呼ばれるプロセスで、以前のバージョンの Android で API を使用できる場合があります。サポートされている API については、desugar で利用可能な 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 が存在しない場合(および toolchain リゾルバが定義されている場合)、1 つダウンロードします。
  • ソースコードからの呼び出し用にツールチェーンの Java API を公開します。
  • Java 言語バージョンを使用して Java ソースをコンパイルします。
  • sourceCompatibilitytargetCompatibility のデフォルト値を指定します。

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

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

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 のバージョンが異なります。targetCompatibilityjvmTarget を増やすと、追加の Java 機能を利用できます。ただし、この場合、機能を利用できるように Android SDK の最小バージョンも増やす必要があります。

targetCompatibilitysourceCompatibility 以上の値でなければなりません。実際には、sourceCompatibilitytargetCompatibilityjvmTarget には通常同じ値を使用します。次のように設定できます。

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 ツールチェーンを使用することをおすすめします。