Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

자바 8 언어 기능 및 API 사용

Android Gradle 플러그인 3.0.0 이상은 자바 7 언어 기능 일체를 모두 지원하고, Java 8 언어 기능의 경우 플랫폼 버전에 따라 각각 다르게 부분적으로 지원합니다. Android Gradle 플러그인 4.0.0 이상을 사용하여 앱을 빌드하면 앱의 최소 API 수준 없이도 다양한 자바 8 언어 API를 사용할 수 있습니다.

이 페이지에서는 사용할 수 있는 자바 8 언어 기능, 이러한 기능을 사용할 프로젝트를 올바르게 구성하는 방법 및 발생할 수 있는 알려진 문제에 대해 설명합니다. 다음 동영상을 통해 개요를 알아보세요.

참고: Android용 앱 개발 시 자바 8 언어 기능을 사용하는 것은 선택사항입니다. 프로젝트의 소스 및 대상 호환성 값을 자바 7로 유지할 수는 있지만 JDK 8을 사용하여 컴파일해야 합니다.

Android Gradle 플러그인은 특정 자바 8 언어 기능과 이러한 기능을 사용하는 타사 라이브러리를 사용하기 위한 내장 지원 기능을 제공합니다. 그림 1과 같이 기본 도구 모음은 클래스 파일을 dex 코드에 D8/R8 컴파일하는 일환으로, desugar라는 바이트 코드 변환을 실행하여 새로운 언어 기능을 구현합니다.

그림 1. desugar 바이트 코드 변환을 사용하는 자바 8 언어 기능 지원.

자바 8 언어 기능 지원(Android Gradle 플러그인 3.0.0 이상)

지원되는 자바 8 언어 기능을 사용하려면 3.0.0 이상으로 Android 플러그인을 업데이트하세요. 그런 다음 아래에 나와 있는 것처럼, 자바 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
  }
  // For Kotlin projects
  kotlinOptions {
    jvmTarget = "1.8"
  }
}

Android Gradle 플러그인 3.0.0 이상을 사용하여 앱을 빌드할 때 이 플러그인은 일부 자바 8 언어 기능을 지원하지 않습니다. 이제 다음 언어 기능을 모든 API 수준에서 사용할 수 있습니다.

자바 8 언어 기능 참고
람다 표현식 Android는 람다 표현식의 직렬화를 지원하지 않습니다.
메서드 참조  
형식 주석 형식 주석 정보는 런타임이 아닌 컴파일 시간에만 확인할 수 있습니다. 또한 이 플랫폼은 API 수준 24 이하에서 TYPE을 지원하지만 ElementType.TYPE_USE 또는 ElementType.TYPE_PARAMETER를 지원하지는 않습니다.
기본 및 정적 인터페이스 메서드  
주석 반복  

위에서 설명한 자바 8 언어 기능 외에도, 플러그인 버전 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 또는 이전 버전에서 그 라이브러리를 계속 사용하려면 코드 축소를 활성화하여 사용되지 않는 메서드를 제거하세요. 그래도 효과가 없으면 지원되지 않는 메서드를 사용하지 않는 다른 라이브러리를 사용해 봅니다.

Android Gradle 플러그인 3.0.0에서 사용 가능한 자바 8+ 언어 기능 디슈가링을 진행해도 추가 클래스와 API(예: java.util.stream.*)를 이전 Android 버전에서 사용할 수는 없습니다. 부분 자바 API 디슈가링을 위한 지원은 Android Gradle 플러그인 4.0.0 이상에서 제공되며, 다음 섹션에 설명되어 있습니다.

자바 8+ API 디슈가링 지원(Android Gradle 플러그인 4.0.0 이상)

Android Gradle 플러그인 4.0.0 이상을 사용하여 앱을 빌드하면 이 플러그인은 앱의 최소 API 수준 없이도 다양한 자바 8 언어 API를 사용할 수 있도록 지원을 확대합니다.

플러그인 4.0.0 이상에서 자바 언어 API도 디슈가링하도록 디슈가링 엔진을 확장하기 때문에 이전 플랫폼 버전을 위한 이 같은 추가 지원이 가능합니다. 따라서 최신 Android 출시(java.util.streams 등)에서만 사용할 수 있었던 표준 언어 API를 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.OptionalIntjava.util.OptionalDouble)과 위의 API에서 유용하게 사용할 수 있는 몇 가지 새로운 클래스
  • 일부 java.util.concurrent.atomic에 추가된 사항(AtomicInteger, AtomicLong, AtomicReference의 새 메서드)
  • ConcurrentHashMap(Android 5.0 버그 수정 포함)

지원되는 API의 전체 목록을 보려면 디슈가링을 통해 사용할 수 있는 자바 8+ API를 참고하세요.

이러한 언어 API를 지원하기 위해 플러그인에서는 누락된 API의 구현을 포함하는 별도의 라이브러리 DEX 파일을 컴파일하고 이를 앱에 포함합니다. 디슈가링 프로세스를 사용하면 앱 코드를 다시 작성하여 런타임에 이 라이브러리를 대신 사용할 수 있습니다.

Android 플랫폼의 모든 버전에서 이러한 언어 API를 지원하려면 4.0.0(또는 그 이상)으로 Android 플러그인을 업데이트하고 앱 모듈build.gradle 파일에 다음을 포함하세요.

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 {
  coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
}

다음의 경우 라이브러리 모듈build.gradle 파일에 위 코드 스니펫을 포함해야 할 수 있습니다.

  • 라이브러리 모듈의 계측 테스트는 이러한 언어 API를 직접 또는 라이브러리 모듈이나 모듈의 종속 항목을 통해 사용합니다. 이는 계측 테스트 APK에 누락된 API를 제공하기 위함입니다.

  • 라이브러리 모듈에서 린트를 독립적으로 실행하는 것이 좋습니다. 이렇게 하면 린트에서 언어 API의 올바른 사용을 인식하여 거짓 경고 보고를 방지하도록 할 수 있습니다.