lightbulb_outline Please take our October 2018 developer survey. Start survey

Java 8 言語機能の使用

Android Studio 3.0 以降では、プラットフォームのバージョンごとに異なる Java 7 のすべての言語機能と Java 8 の言語機能のサブセットをサポートしています。 このページでは、利用可能な Java 8 言語機能や、それらを利用するためのプロジェクトの適切な設定方法、想定される既知の問題について紹介します。

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

Android Studio では、特定の Java 8 言語機能とそれらを使用するサードパーティ ライブラリのビルトイン サポートを提供しています。 図 1 に示すように、デフォルトのツールチェーンは、javac コンパイラーの出力に対して desugar と呼ばれるバイトコード変換を実行することにより、この新しい言語機能を実装します。 Jack のサポートは終了したため、まず Jack を無効にしてから、デフォルトのツールチェーンにビルトインされている Java 8 サポート機能をご利用ください。

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

サポートされる 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
  }
}

注: Android Studio でプロジェクトが Jack、Retrolambda、またはDexGuard を使用していることが検出されると、IDE ではこれらのツールが提供する Java 8 サポートが使用されますが、 デフォルトのツールチェーンに移行することを検討してください。

サポートされる Java 8 の言語機能と API

Android Studio はすべての Java 8 言語機能をサポートしているわけではありませんが、IDE の将来のリリースにはさらに多くの機能が追加されます。 次の表に示すように、現在、使用している minSdkVersion に応じて特定の機能と API が利用可能です。

Java 8 言語機能 互換性のある minSdkVersion
ラムダ式 すべて。 ただし、ラムダ式のシリアル化は、ラムダ式で取得したすべての値がシリアル化できる場合にのみサポートされます。
メソッド参照 すべて。
型アノテーション すべて。 ただし、型アノテーション情報は、実行時ではなくコンパイル時に使用できます。 また、プラットフォームは API レベル 24 以前の TYPE をサポートしますが、ElementType.TYPE_USEElementType.TYPE_PARAMETER はサポートしません。
デフォルトおよび静的インターフェースのメソッド すべて。
繰り返しアノテーション すべて。
Java 8 言語 API 互換性のある minSdkVersion
java.lang.annotation.Repeatable API レベル 24 以降。
AnnotatedElement.getAnnotationsByType(Class) API レベル 24 以降。
java.util.stream API レベル 24 以降。
java.lang.FunctionalInterface API レベル 24 以降。
java.lang.reflect.Method.isDefault() API レベル 24 以降。
java.util.function API レベル 24 以降。

Android Studio 3.0 以降では、上記の Java 8 言語機能と API に加えて、 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 Studio でプロジェクトが Jack、Retrolambda、または DexGuard を使用していることが検出されると、IDE ではこれらのツールが提供する Java 8 サポートが使用されます。 ただし、デフォルトのツールチェーンとは異なり、これらのツールには一部の機能とサポートが含まれていません。 したがって、このセクションの手順に従って、Android Studio のデフォルトのツールチェーンに移行してください。

Jack からの移行

この通知でお知らせしたとおり、Jack ツールチェーンのサポートは終了しました。 プロジェクトが Jack に依存している場合は、Android Studio のデフォルトのツールチェーンにビルトインされている Java 8 サポートの使用に切り替える必要があります。 デフォルトのツールチェーンを使用すれば、Java 8 言語機能、Instant Run、中間 .class ファイルに依存しているツールを使用するサードパーティ ライブラリもサポートされます。

Jack を無効にして、デフォルトのツールチェーンに切り替えるには、次のように、モジュールの build.gradle ファイルから jackOptions ブロックを削除します。

android {
    ...
    defaultConfig {
        ...
        // Remove this block.
        jackOptions {
            enabled true
            ...
        }
    }

    // Keep the following configuration in order to target Java 8.
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

Retrolambda からの移行

Android Studio のデフォルトのツールチェーンとは異なり、Retrolambda では、Java 8 言語機能を使用するサードパーティ ライブラリがサポートされません。 デフォルトのツールチェーンに移行するには、次のように、プロジェクト レベルの build.gradle ファイルから Retrolambda 依存関係を削除します。

buildscript {
  ...
   dependencies {
      // Remove the following dependency.
      classpath 'me.tatarka:gradle-retrolambda:<version_number>'
   }
}

さらに、次のように、各モジュールの build.gradle ファイルから Retrolambda プラグインと retrolambda ブロックを削除します。

// Remove the following plugin.
apply plugin: 'me.tatarka.retrolambda'
...
// Remove this block after migrating useful configurations.
retrolambda {
    ...
    // If you have arguments for the Java VM you want to keep,
    // move them to your project's gradle.properties file.
    jvmArgs '-Xmx2048m'
}

Java 8 言語機能のサポートの無効化

Java 8 言語機能のサポートに関連する問題が発生している場合は、gradle.properties ファイルに次のコードを追加して、Java 8 言語機能のサポートを無効にできます。

android.enableDesugar=false

Java 8 のサポートの改善のために、バグの報告をお願いします。