lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Java 8 언어 기능 사용

Android Studio 3.0 이상은 Java 7 언어 기능 일체를 모두 지원하고, Java 8 언어 기능의 경우 버전에 따라 각각 다르게 부분적으로 지원합니다. 이 페이지에서는 사용할 수 있는 Java 8 언어 기능, 이러한 기능을 사용할 프로젝트를 올바르게 구성하는 방법 및 발생할 수 있는 알려진 문제에 대해 설명합니다.

참고: Android용 앱을 개발할 때에는 Java 8 언어 기능을 사용하는 것이 가장 좋습니다. 프로젝트의 소스 및 대상 호환성 값을 Java 7로 유지할 수는 있지만, JDK 8을 사용하여 컴파일해야 합니다.

Android Studio는 특정 Java 8 언어 기능과 이러한 기능을 사용하는 타사 라이브러리를 사용하기 위한 내장 지원 기능을 제공합니다. 그림 1과 같이, 기본 툴체인은 javac 컴파일러의 출력에 대해 desugar라는 바이트코드 변환을 수행하여 새로운 언어 기능을 구현합니다. 더 이상 Jack이 지원되지 않으며, 기본 툴체인에 기본 제공되는 Java 8 지원을 사용하려면 먼저 Jack을 비활성화해야 합니다.

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

지원되는 Java 8 언어 기능을 사용하기 시작하려면 3.0.0 이상으로 Android 플러그인을 업데이트하세요. 그런 다음, 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의 향후 릴리스에 더 많은 기능이 추가될 예정입니다. 어떤 minSdkVersion을 사용 중인지에 따라, 아래 표의 설명과 같이 특정 기능과 API를 사용할 수 있습니다.

Java 8 언어 기능 호환 가능 minSdkVersion
람다 식 모두. 하지만 람다에 의해 캡처되는 값을 전부 직렬화할 수 있을 때만 람다 직렬화가 지원됩니다.
메서드 참조 모두.
형식 주석 모두. 하지만 형식 주석 정보는 런타임이 아니라 컴파일 시간에 확인할 수 있습니다. 또한, 이 플랫폼은 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 이상에서는 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 Studio에서 개발자의 프로젝트가 Jack, Retrolambda 또는 DexGuard를 사용 중임을 인식하는 경우 IDE는 그러한 도구에서 제공되는 Java 8 지원을 대신 사용합니다. 하지만 기본 툴체인과 비교해 볼 때, 이들 도구는 몇 가지 기능과 지원 측면에서 부족한 점이 있습니다. 따라서 이 섹션의 안내에 따라 Android Studio의 기본 툴체인으로 마이그레이션하시기 바랍니다.

Jack에서 마이그레이션

이번 발표에 따라 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 블록을 제거하세요.

// Remove the following plugin.
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 언어 기능에 대한 지원 중지

Java 8 언어 기능에 대한 지원과 관련된 문제가 발생하는 경우 gradle.properties 파일에 다음을 추가하여 이 기능을 중지할 수 있습니다.

android.enableDesugar=false

버그를 제출해 주시면 Java 8을 위한 지원 개선에 큰 도움이 될 것입니다.