AndroidでJava 8を使う (2017年版)


これまでAndroidでJava 8の言語機能を使うにはRetrolambdaかJackを用いる必要がありました。
今年の3月にGoogleはJackを廃止するアナウンスをし、従来のjavac + dxツールチェーン上でJava 8をサポートする方針に切り替えました。
Android Studio 2.4 Preview 4以降ではJackが廃止され、新しい方法でJava 8の言語機能がサポートされています。

以下はまだプレビュー版での情報ですが、正式版に組込まれればJava 8への移行がよりしやすくなるはずです。

ツールチェーンの変更

2.4 Preview 4以降では、標準のjavacツールチェーンにdesugarというツールを挟むことでJava 8の言語機能を利用可能にしています。

  • 標準の javac + dxツールチェーン:
    javac.java.class)→ dx.class.dex
  • Jack ツールチェーン:
    Jack.java.jack.dex
  • 2.4 Preview 4で導入されたdesugar ツールチェーン:
    javac.java.class)→ desugar.class.class)→ dx.class.dex

Gradleでビルド(assembleDebug)してみると以下のタスクが実行されるのがわかります。

:app:extractJava8LangSupportJar
:app:transformClassesWithDesugarForDebug

desugarを使ったツールチェーンでは、Java Bytecode(classファイル)が生成されるためJacocoやTransform APIを使ったInstant Runなどが使えます。
またData Bindingとも併用できます。

ビルトインのJava 8を使う手順

Android Studio 2.4 Preview 4以降をインストールする

Android Studio 2.4 Preview 4以降でGradleのAndroid Plugin 2.4.0-alpha4以降(2017-05-08時点では2.4.0-alpha7)を使います。
安定版のAndroid Studio 2.3以前に作成したプロジェクトを開くと、プロジェクトのbuild.gradleをアップデートするように促されます

build.gradle
buildscript {
  ...
  dependencies {
    classpath 'com.android.tools.build:gradle:2.4.0-alpha7'
  }
  ...
}

なお、Gradleのバージョンが古いままJava 8を使おうとすると以下のようなエラーが出力されます。

Error:Jack is required to support java 8 language features. Either enable Jack or remove sourceCompatibility JavaVersion.VERSION_1_8.

Javaソースコードの互換性をJava 8に設定する

アプリモジュール側のbuild.gradleを更新します。
ここはJackやRetrolambdaを使っている場合と同じです。

build.gradle
android {
  ...
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
  ...
}

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

Android Studio 2.4 Preview 7時点で以下の言語機能がサポートされています。

  • ラムダ式
  • メソッド参照
  • タイプアノテーション
  • デフォルトおよび静的インターフェースのメソッド (minSdkVersion 24以上)
  • 反復アノテーション

Jackと同じ感じですね。

その他、API Level 24以降でjava.util.streamなどいくつかのJava 8のAPIがサポートされます。
(minSdkVersion 24未満でStream APIを使うにはLightweight-Stream-APIstreamsupportを使いましょう)