Android Studio 3.0及以上版本支持所有Java 7语言功能,以及部分Java 8语言功能(具体因平台版本而异)。本页介绍您可以使用的Java 8语言功能,如何正确配置项目以使用这些功能以及您可能遇到的任何已知问题。
注:在开发Android应用时,可以选择使用Java 8语言功能。您可以将项目的源代码和目标代码兼容性值保留为Java 7,但仍然使用JDK 8进行编译。
Android Studio为使用部分Java 8语言功能及利用这些功能的第三方库提供内置支持。如图1所示,默认工具链对javac编译器的输出执行字节码转换(称为desugar),从而实现新语言功能。 杰克不再受支持,需要您首先停用杰克才能使用默认工具链内置的Java的8支持。
图1.采用desugar字节码转换的的Java 8语言功能支持。
要开始使用受支持的Java 8语言功能,请更新Android插件到3.0.0(或更高版本)。然后,针对使用(包括在源代码中或通过依赖项使用)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版本将会增加更多功能。目前,部分功能和API已可使用,具体取决于您所使用的minSdkVersion,详见下表。
Java 8语言功能 兼容的 minSdkVersion
Lambda表达式 任意。然而,只有在Lambda采集的所有值可序列化时才支持Lambda序列化。
函数引用 任意。
类型注解 任意。然而,类型注解信息仅在编译时可用,在运行时不可用。此外,在API级别24及更低级别中,平台支持TYPE,而不支持ElementType.TYPE_USE或ElementType.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或更高级别。
除了上述Java 8语言功能和API之外,Android Studio 3.0及更高版本还将对-with-resources的支持扩展到所有级别的Android API。 try
Desugar目前暂不支持MethodHandle.invoke或MethodHandle.invokeExact。如果您的源代码或任一模块依赖项使用了其中一种函数,则需指定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,则应执行迁移,以便享受到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块:
//删除以下插件。
申请插件:‘me.tatarka.retrolambda’
…
//迁移有用配置后删除此块。
retrolambda {
…
//如果您想要保留Java VM的参数,
//将它们移动到项目的gradle.properties文件中。
jvmArgs’-Xmx2048m’
}
停用对Java 8语言功能的支持
如果您遇到与Java 8语言功能支持相关的问题,可在gradle.properties文件中加入以下代码来停用此支持:
android.enableDesugar=false
为了帮助我们改进对Java 8的支持,请提交错误。