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 言語機能の概要については、次の動画をご覧ください。

Android Gradle プラグインは、特定の Java 8 言語機能と、それを使用するサードパーティ ライブラリを利用するための組み込みのサポートを提供します。図 1 に示すように、デフォルトのツールチェーンは、クラスファイルを DEX コードに変換する D8 / R8 コンパイルの一環として desugar と呼ばれるバイトコード変換を実行することにより、新しい言語機能を実装します。

desugar バイトコード変換を使用した Java 8 言語機能のサポート
図 1. desugar バイトコード変換を使用した Java 8 言語機能のサポート

Java 8 言語機能のサポート(Android Gradle プラグイン 3.0.0+)

サポートされている Java 8 言語機能を使用するには、以下を行います。

  1. 3.0.0 以上に Android Gradle プラグインをアップデートします。
  2. (ソースコード内で、または依存関係を通して)Java 8 言語機能を使用するモジュールごとに、次のようにモジュールの build.gradle ファイルまたは build.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 言語機能 備考
ラムダ式 Android はラムダ式のシリアル化をサポートしていません。
メソッド参照  
型アノテーション 型アノテーション情報はコンパイル時にのみ使用できます。実行時は使用できません。また、プラットフォームは API レベル 24 以下の TYPE をサポートしますが、ElementType.TYPE_USE または ElementType.TYPE_PARAMETER はサポートしません。
デフォルトおよび静的インターフェース メソッド  
繰り返しアノテーション  

Android Gradle プラグイン バージョン 3.0.0 以上では、上記の Java 8 言語機能に加えて、 try-with-resources のサポートがすべての Android API レベルに拡張されています。

desugar は、MethodHandle.invoke または MethodHandle.invokeExact をサポートしていません。ソースコードまたはいずれか 1 つのモジュール依存関係でこれらのメソッドのいずれかが使用されている場合は、minSdkVersion 26 以上を指定する必要があります。そうしないと、次のエラーが表示されます。

Dex: Error converting bytecode to dex:
Cause: signature-polymorphic method called without --min-sdk-version >= 26

invoke メソッドまたは invokeExact メソッドがライブラリの依存関係に含まれている場合でさえ、モジュールがそれらを使用しないことがあります。したがって、minSdkVersion 25 以下でそのライブラリを引き続き使用するには、コード圧縮を有効化して、使用されないメソッドを削除してください。この方法がうまくいかない場合は、サポートされていないメソッドを使用しない代替ライブラリの使用を検討してください。

Android Gradle プラグイン 3.0.0 以上で利用可能な Java 8+ 言語機能の desugar により、追加のクラスと API(java.util.stream.* など)を、古い Android リリースで利用可能にすることはできません。 Android Gradle プラグイン 4.0.0 以上では、Java API の desugar の部分的なサポートを利用できます。これについては、次のセクションで説明します。

Java 8+ API の desugar のサポート(Android Gradle プラグイン 4.0.0+)

Android Gradle プラグイン 4.0.0 以上を使用してアプリをビルドする場合、このプラグインは、アプリの最小 API レベルを必要とすることなく、いくつかの Java 8 言語 API のサポートを拡張します。Android Gradle プラグイン 7.4.0 以上では、desugar ライブラリ 2.0.0 以上でいくつかの Java 11 言語 API も使用できます。

4.0.0 以上のプラグインは desugar エンジンを拡張して Java 言語 API も desugar するため、古いプラットフォーム バージョンの追加サポートが可能です。これにより、最近の Android リリースでのみ利用可能だった標準の言語 API(java.util.streams など)を、古いバージョンの Android に対応したアプリでも使用できるようになります。

Android Gradle プラグイン 4.0.0 以上を使用してアプリをビルドする場合は、次の API のセットがサポートされます。

  • 連続ストリーム(java.util.stream
  • java.time のサブセット
  • java.util.function
  • java.util.{Map,Collection,Comparator} の最新の追加 API
  • オプション(java.util.Optionaljava.util.OptionalIntjava.util.OptionalDouble)および一部の新しいクラス
  • java.util.concurrent.atomic の追加 API(AtomicIntegerAtomicLongAtomicReference の新しいメソッド)
  • ConcurrentHashMap(Android 5.0 のバグを修正)

Android Gradle プラグイン 7.4.0 以上では、java.nio.file パッケージのサブセットなど、その他の Java 11 API がサポートされます。

サポートされている API の全一覧については、desugar で利用可能な Java 8+ APIdesugar で利用可能な Java 11+ API をご覧ください。

これらの言語 API をサポートするため、プラグインは不足している API の実装を含む別個の DEX ファイルをコンパイルしてアプリに追加します。desugar プロセスはアプリのコードを書き換えて、実行時にこのライブラリが代わりに使用されるようにします。

Android プラットフォームのすべてのバージョンでこれらの言語 API のサポートを有効にするには、以下を行います。

  1. Android Gradle プラグインをアップデートして 4.0.0 以上にします。
  2. アプリ モジュールbuild.gradle ファイルまたは build.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.gradle ファイルまたは build.gradle.kts ファイルにも上記のコード スニペットを含める必要があります。

  • ライブラリ モジュールのインストルメンテーション テストで、このような言語 API を直接使用するか、ライブラリ モジュールまたはその依存関係を通じて使用する場合。これは、インストルメンテーション テスト APK を実行するために不足している API を提供する場合に行います。

  • ライブラリ モジュールの lint を単独で実行する場合。これは、言語 API が有効に使用されていることを lint が認識し、誤った警告を報告しないようにするために行います。

また、API の脱糖は圧縮と組み合わせることができますが、R8 圧縮ツールを使用する場合に限られます。

バージョン

次の表に、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 ファイルをご覧ください。