Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

Java 8 言語機能と API を使用する

Android Gradle プラグイン 3.0.0 以降では、すべての Java 7 言語機能と、プラットフォームのバージョンごとに異なる Java 8 言語機能のサブセットがサポートされます。Android Gradle プラグイン 4.0.0 以上を使用してアプリをビルドする場合は、アプリの最小 API レベルを必要とすることなく、多数の Java 8 言語 API を使用できます。

このページでは、利用可能な Java 8 言語機能、それを利用するためのプロジェクトの適切な設定方法、そして遭遇する可能性がある既知の問題について説明します。概要については、次の動画もご覧ください。

注: Android 向けのアプリを開発する際、必ずしも Java 8 言語機能を使用する必要はありません。プロジェクトのソースおよびターゲットの互換性の値の設定を Java 7 のままにすることもできます。ただし、その場合もコンパイルには JDK 8 を使用する必要があります。

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

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

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

サポートされている Java 8 言語機能の使用を開始するには、3.0.0(またはそれ以上)に Android プラグインをアップデートします。その後、(ソースコード内で、または依存関係を通して)Java 8 言語機能を使用するモジュールごとに、次のようにモジュールの build.gradle ファイルを更新します。

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 はサポートしません。
デフォルト メソッドと静的インターフェース メソッド  
繰り返しアノテーション  

プラグイン バージョン 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 のサポートを拡張します。

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)および上記の API で役立つその他の新しいクラス
  • java.util.concurrent.atomic の追加 API(AtomicIntegerAtomicLongAtomicReference の新しいメソッド)
  • ConcurrentHashMap(Android 5.0 のバグを修正)

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

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

Android プラットフォームのすべてのバージョンでこれらの言語 API のサポートを有効にするには、4.0.0(またはそれ以上)に Android プラグインをアップデートして、モジュールの build.gradle ファイルに以下の行を含めます。

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 {
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
}