Android Gradle 플러그인 3.0.0 이상에서는 모든 Java 7 언어 기능과 플랫폼 버전에 따라 다른 Java 8 언어 기능의 일부를 지원합니다. Android Gradle 플러그인 4.0.0 이상을 사용하여 앱을 빌드할 때 앱의 최소 API 수준 없이도 일부 Java 8 언어 API를 사용할 수 있습니다.
이 페이지에서는 사용할 수 있는 Java 8 언어 기능, 이러한 기능을 사용할 프로젝트를 올바르게 구성하는 방법, 발생할 수 있는 알려진 문제에 관해 설명합니다. Java 8 언어 기능에 관한 개요는 다음 동영상을 참고하세요.
Android Gradle 플러그인은 특정 Java 8 언어 기능과 이러한 기능을 사용하는 서드 파티 라이브러리를 사용하기 위한 내장 지원 기능을 제공합니다. 기본 도구 모음은 클래스 파일을 DEX 코드에 D8/R8 컴파일하는 과정의 일환으로, desugar
라는 바이트 코드 변환을 실행하여 새로운 언어 기능을 구현합니다(그림 1 참고).
Java 8 언어 기능 지원(Android Gradle 플러그인 3.0.0 이상)
지원되는 Java 8 언어 기능을 사용하려면 다음 단계를 따르세요.
- 3.0.0 이상으로 Android Gradle 플러그인을 업데이트합니다.
- 소스 코드에서 또는 종속 항목을 통해 Java 8 언어 기능을 사용하는 각 모듈의 경우 다음과 같이 모듈의
build.gradle
또는build.gradle.kts
파일을 업데이트합니다.
Kotlin
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 } // For Kotlin projects kotlinOptions { jvmTarget = "1.8" } }
Groovy
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 } // For Kotlin projects kotlinOptions { jvmTarget = "1.8" } }
Android Gradle 플러그인 3.0.0 이상을 사용하여 앱을 빌드할 때 플러그인은 일부 Java 8 언어 기능을 지원하지 않습니다. 다음 언어 기능을 모든 API 수준에서 사용할 수 있습니다.
Java 8 언어 기능 | 참고 |
---|---|
람다 표현식 | Android는 람다 표현식의 직렬화를 지원하지 않습니다. |
메서드 참조 | |
형식 주석 | 형식 주석 정보는 런타임이 아닌 컴파일 시간에만 확인할 수 있습니다. 이 플랫폼은 API 수준 24 이하에서 TYPE 을 지원하지만 ElementType.TYPE_USE 또는 ElementType.TYPE_PARAMETER 를 지원하지는 않습니다.
|
기본 및 정적 인터페이스 메서드 | |
주석 반복 |
이러한 Java 8 언어 기능 외에도 Android Gradle 플러그인 버전 3.0.0 이상에서는
try
-with-resources 지원을 모든 Android API 수준으로 확장합니다.
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
이하 버전에서 해당 라이브러리를 계속 사용하려면 코드 축소를 활성화하여 사용되지 않는 메서드를 제거하세요. 그래도 효과가 없으면 지원되지 않는 메서드를 사용하지 않는 다른 라이브러리를 사용해 봅니다.
Java 8+ 언어는 Android Gradle 플러그인 3.0.0 이상에서 디슈가링 기능을 제공하지만 이전 Android 출시에서 사용하도록 추가 클래스 및 API(예: java.util.stream.*
)를 제공하지는 않습니다.
부분 Java API 디슈가링은 Android Gradle 플러그인 4.0.0 이상에서 지원됩니다(다음 섹션 참고).
Java 8+ API 디슈가링 지원(Android Gradle 플러그인 4.0.0 이상)
Android Gradle 플러그인 4.0.0 이상을 사용하여 앱을 빌드하고 있다면 이 플러그인은 앱의 최소 API 수준 없이도 다양한 Java 8 언어 API를 사용할 수 있도록 지원을 확대합니다. Android Gradle 플러그인 7.4.0 이상을 사용하면 디슈가링된 라이브러리 2.0.0 이상에서 여러 Java 11 언어 API를 사용할 수 있습니다.
플러그인 4.0.0 이상에서 Java 언어 API도 디슈가링하도록 디슈가링 엔진을 확장하기 때문에 이전 플랫폼 버전을 위한 이 같은 추가 지원이 가능합니다. 최신 Android 출시에서만 사용할 수 있었던 표준 언어 API(예: java.util.streams
)를 이전 Android 버전을 지원하는 앱에 포함할 수 있습니다.
Android Gradle 플러그인 4.0.0 이상을 사용하여 앱을 빌드할 경우 다음 API가 지원됩니다.
- 순차적 스트림(
java.util.stream
) java.time
의 하위 집합java.util.function
- 최근
java.util.{Map,Collection,Comparator}
에 추가된 사항 - 선택사항 (
java.util.Optional
,java.util.OptionalInt
,java.util.OptionalDouble
) 및 일부 새 클래스 - 일부
java.util.concurrent.atomic
에 추가된 사항(AtomicInteger
,AtomicLong
,AtomicReference
의 새 메서드) ConcurrentHashMap
(Android 5.0 버그 수정 포함)
Android Gradle 플러그인 7.4.0 이상에서는 java.nio.file
패키지의 하위 집합과 같은 추가 Java 11 API가 지원됩니다.
지원되는 API의 전체 목록은 디슈가링을 통해 사용할 수 있는 Java 8+ API와 디슈가링을 통해 사용할 수 있는 Java 11+ API를 참고하세요.
이러한 언어 API를 지원하기 위해 플러그인에서는 누락된 API의 구현을 포함하는 별도의 DEX 파일을 컴파일하고 이를 앱에 포함합니다. 디슈가링 프로세스를 사용하면 앱 코드를 다시 작성하여 런타임에 이 라이브러리를 대신 사용할 수 있습니다.
모든 Android 플랫폼 버전에서 이러한 언어 API를 지원하려면 다음 단계를 따르세요.
- 4.0.0 이상으로 Android Gradle 플러그인을 업데이트합니다.
- 앱 모듈의
build.gradle
또는build.gradle.kts
파일에 다음을 포함합니다.
Kotlin
android { defaultConfig { // Required when setting minSdkVersion to 20 or lower multiDexEnabled = true } compileOptions { // Flag to enable support for the new language APIs // For AGP 4.1+ isCoreLibraryDesugaringEnabled = true // For AGP 4.0 // coreLibraryDesugaringEnabled = true // Sets Java compatibility to Java 8 sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } } dependencies { // For AGP 7.4+ coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.3") // For AGP 7.3 // coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.3") // For AGP 4.0 to 7.2 // coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.9") }
Groovy
android { defaultConfig { // Required when setting minSdkVersion to 20 or lower multiDexEnabled true } compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled true // Sets Java compatibility to Java 8 sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { // For AGP 7.4+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' // For AGP 7.3 // coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.3' // For AGP 4.0 to 7.2 // coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.9' }
다음의 경우 라이브러리 모듈의 build.gradle
또는 build.gradle.kts
파일에 위 코드 스니펫을 포함해야 할 수 있습니다.
라이브러리 모듈의 계측 테스트가 이러한 언어 API를 직접 또는 라이브러리 모듈이나 모듈의 종속 항목을 통해 사용하는 경우. 이는 누락된 API를 계측 테스트 APK에 제공하기 위함입니다.
라이브러리 모듈에서 린트를 독립적으로 실행하려는 경우. 이렇게 하면 린트에서 언어 API의 올바른 사용을 인식하여 거짓 경고 보고를 방지하도록 할 수 있습니다.
또한 API 디슈가링은 축소와 결합할 수 있지만 R8 축소기를 사용할 때만 가능합니다.
버전
다음 표에는 Java 8+ API 라이브러리의 버전과 각 버전을 지원하는 최소 Android Gradle 플러그인 버전이 나와 있습니다.
버전 | 최소 Android Gradle 플러그인 버전 |
---|---|
1.1.9 | 4.0.0 |
1.2.3 | 7.3.0 |
2.0.3 | 7.4.0-alpha10 |
Java 8+ API 라이브러리 버전에 관한 자세한 내용은 desugar_jdk_libs
GitHub 저장소의 CHANGELOG.md 파일을 참고하세요.