Android Studio 3.0 Preview 1 でJava 8 がサポート

# Android Studio 3.0 Preview 1 でJava 8 がサポート
初投稿です。お見苦しいところもあるかと思いますが、ご容赦ください。

普段C# をメインに仕事していて、ラムダ式を積極的に使っています。
それと同じようにAndroid 開発もやりたいのですが、
ラムダ式が使えるJava 8 のサポートが微妙（※１）でした……。

**しかし、2017 年に状況が変わったようです。**
  
[AndroidでJava 8を使う (2017年版)](http://qiita.com/kamimoo/items/e0a07f3589086f5e4e2a) でも紹介されているように、
Android Studio 次期バージョンで組み込まれるようです。  

今回、その出典元と思われる記事[Use Java 8 language features](https://developer.android.com/studio/write/java8-support.html) を見つけました。
英語の文章なので、翻訳がてらメモしていきたいと思います。
読み間違いがあるかもしれませんが、ご了承くださいm(_ _)m

※１：Jack というコンパイラに差し替えるのですが、ビルド時間が長くてとても困りました(T_T)
→ [Java 8 の言語機能を使う](https://developer.android.com/guide/platform/j8-jack.html?hl=ja)
→ Jack は実用的でなかったので、代わりにRetrolambda を使っていた人が多いのではと思っています。多分……。



## 導入方法
[Android plugin](https://developer.android.com/studio/releases/gradle-plugin.html#updating-plugin) を```3.0.0-alpha1``` 以降にして
モジュール直下の```build.gradle``` に下記を追加します。

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



## サポートされるJava 8 の言語仕様、API
Android Studio はすべてのJava 8 の言語仕様をサポートするわけではありません。
しかし、いくつかの言語使用はAndroid Studio の次期バージョンでサポートされる予定です。
ただし、```minSdkVersion``` によっては使えないものがあります。

### Java 8 言語仕様
Java 8 言語仕様 | minSdkVersion
--- | ---
[ラムダ式](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) | 条件付きですべて（※１）
[メソッドリファレンス](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html) | すべて
[タイプアノテーション](https://docs.oracle.com/javase/tutorial/java/annotations/type_annotations.html) | 条件付きですべて(※２)
[デフォルトおよび静的インターフェースのメソッド](https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html) | すべて
[反復アノテーション](https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html) | すべて

※１
ラムダ式シリアライズは、ラムダ式で使われている変数すべてがシリアライズ可能の場合使えます

※２
タイプアノテーション情報はコンパイル時は使えるが、実行時は不可。
また[TYPE](https://developer.android.com/reference/java/lang/annotation/ElementType.html#TYPE) はAPI 24 以下で使えるが、```ElementType.TYPE_USE```,```ElementType.TYPE_PARAMETER``` は不可

### Java 8 API
Java 8 API | minSdkVersion
--- | ---
[java.lang.annotation.Repeatable](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Repeatable.html) | Android 7.0(API 24) 以降
[AnnotatedElement.getAnnotationsByType(Class)](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AnnotatedElement.html#getAnnotationsByType-java.lang.Class-) | Android 7.0(API 24) 以降
[java.util.stream](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) | Android 7.0(API 24) 以降
[java.lang.FunctionalInterface](https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html) | Android 7.0(API 24) 以降
[java.lang.reflect.Method.isDefault()](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#isDefault--) | Android 7.0(API 24) 以降
[java.util.function](https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html) | Android 7.0(API 24) 以降

### その他
* Android Studio 3.0 Preview 1 以降では、[try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) がすべてのAndroid API レベルで使えるようになります。  
→ 今まではAndroid 4.4(API 19) 以降でしか使えませんでした。  
→ 参考：[JDK7でAndroid開発、していいの？ダメなの？](http://qiita.com/hidekuro/items/6a252c82132ed5d279a4)



## ツールチェインの移行
### Jack
Jack ツールチェインは[廃止予定](https://android-developers.googleblog.com/2017/03/future-of-java-8-language-feature.html)です。
なので、Jack を有効化する```jackOptions``` を```build.gradle``` から取り除いてください。

``` gradle
android {
    ...
    defaultConfig {
        ...
        // ここを削除する
        jackOptions {
            enabled true
            ...
        }
    }

    // 下記の記述は残す
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
```

### Retrolambda
Retrolambda はサードパーティのライブラリ向けのJava 8 機能サポートが欠けています。
なので、Retrolambda の記述を取り除き、Android Studio に含まれるツールチェインを使うようにします。

まず、プロジェクトレベルのの```build.gradle``` の下記の依存性を削除します。

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

次にRetrolambda を使っているモジュールの```build.gradle``` から```retrolambda``` の記述を削除します。

``` gradle
// 下記を削除する
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 の無効化方法
```gradle.properties``` に下記を追記してください。

``` gradle
android.enableDesugar=false
```



## 参考文献
* [Java 8 の言語機能を使う](https://developer.android.com/guide/platform/j8-jack.html?hl=ja) (170706)
* [AndroidでJava 8を使う (2017年版)](http://qiita.com/kamimoo/items/e0a07f3589086f5e4e2a) (170706)
* [Use Java 8 language features](https://developer.android.com/studio/write/java8-support.html) (170706)
* [JDK7でAndroid開発、していいの？ダメなの？](http://qiita.com/hidekuro/items/6a252c82132ed5d279a4) (170706)