Android
AndroidのJava
サーチ…
前書き
Androidは、すべてのJava 7言語機能とプラットフォームバージョンによって異なるJava 8言語機能のサブセットをサポートしています。このページでは、使用できる新しい言語機能、それらを使用するためのプロジェクトの適切な設定方法、および遭遇する可能性のある既知の問題について説明します。
Retrolambdaを使ってJava 8の機能をサブセット化
Retrolambdaを使用すると、ラムダ式、メソッド参照、およびJava 7,6または5でのtry-with-resourcesステートメントでJava 8コードを実行できます。これは、Java 8コンパイル済みバイトコードを変換して古いJavaランタイムで実行できるようにすることで行います。
バックポート言語の機能:
ラムダ式は匿名の内部クラスに変換することによってバックポートされます。これには、ステートレスラムダ式にシングルトンインスタンスを使用して繰り返しオブジェクトを割り当てるのを最適化することが含まれます。メソッド参照は基本的にラムダ式の構文砂糖であり、同じ方法でバックポートされます。
ターゲットのバイトコードのバージョンがJava 7未満の場合、
Throwable.addSuppressed
への呼び出しを削除することで、Try-with-resourcesステートメントがバックポートされます。抑止された例外が取り込まれるのではなくログに記録されるようにするには、構成可能です。Objects.requireNonNull
コールはへの呼び出しに置き換えられObject.getClass
ターゲットバイトコードのバージョンは、Java 7 JDK 9の使用によって生成された合成ヌルチェック下回る場合Objects.requireNonNull
以前のJDKバージョンが使用されるのに対し、Object.getClass
。オプション:
デフォルトメソッドは、静的メソッドとしてコンパニオンクラス(インターフェイス名+ "$")にデフォルトメソッドをコピーし、インターフェイスのデフォルトメソッドを抽象メソッドに置き換え、必要なメソッド実装をそのインターフェイスを実装するすべてのクラスに追加することによってバックポートされます。
静的メソッドをコンパニオンクラス(インターフェイス名+ "$")に移動し、すべてのメソッド呼び出しを変更して新しいメソッドの場所を呼び出すことで、インターフェイスの静的メソッドがバックポートされます。
既知の制限:
Java 8 APIをバックポートしない
インターフェース上のバックポートのデフォルトメソッドと静的メソッドには、すべてのバックポートされたインターフェースと、それを実装するすべてのクラス、またはスタティックメソッドを一緒にバックポートするよう呼び出され、Retrolambdaを1回実行する必要があります。つまり、常にきれいなビルドを行う必要があります。また、バックポートのデフォルトメソッドは、モジュールまたは依存関係の境界を越えて機能しません。
将来のJDK 8ビルドが
invokedynamic
呼び出しごとに新しいクラスの生成を停止した場合に壊れる可能invokedynamic
ます。 Retrolambdaは、java.lang.invoke.LambdaMetafactory
が動的に生成するバイトコードをキャプチャするように動作しjava.lang.invoke.LambdaMetafactory
。そのため、そのメカニズムに対する最適化はRetrolambdaを破損する可能性があります。
Retrolambda gradleプラグインは自動的にRetrolambdaであなたのアンドロイドプロジェクトを構築します。最新版は、 リリースページにあります 。
使用法:
- jdk8をダウンロードしてインストールする
-
build.gradle
以下を追加してください
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'me.tatarka:gradle-retrolambda:<latest version>'
}
}
// Required because retrolambda is on maven central
repositories {
mavenCentral()
}
apply plugin: 'com.android.application' //or apply plugin: 'java'
apply plugin: 'me.tatarka.retrolambda'
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
既知の問題点:
Lambdaを持つJavaファイルでLintが失敗します。 AndroidのリントはJava 8の構文を理解していないため、静かにまたは大声で失敗します。問題を解決する実験的なフォークがあります。
Google Playサービスを使用するとRetrolambdaが失敗します。バージョン5.0.77には、Retrolambdaと互換性のないバイトコードが含まれています。これは、新しいバージョンのプレイサービスで修正する必要があります。アップデートできる場合は、これが推奨されるソリューションになります。この問題を
-noverify
するには、4.4.52などの以前のバージョンを使用するか、jvm argsに-noverify
を追加します。
retrolambda {
jvmArgs '-noverify'
}