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

d8

d8은 Android 스튜디오와 Android Gradle 플러그인에서 프로젝트의 자바 바이트 코드를 Android 기기에서 실행되는 DEX 바이트 코드로 컴파일하는 데 사용하는 명령줄 도구입니다. d8로 앱 코드에서 자바 8 언어 기능을 사용할 수 있습니다.

d8은 Android 빌드 도구 28.0.1 이상에 독립형 도구로도 포함됩니다(android_sdk/build-tools/version/).

일반 사용법

d8은 사용하기 쉽고 다음과 같이 DEX 바이트 코드로 변환하려는 컴파일된 자바 바이트 코드 경로만 필요합니다.

d8 MyProject/app/build/intermediates/classes/debug/*/*.class

입력 바이트 코드는 *.class 파일 또는 컨테이너(예: JAR, APK 또는 ZIP 파일)의 어떤 조합이든 가능합니다. d8의 DEX 파일을 포함하여 DEX 출력으로 병합할 수도 있으며 이는 증분 빌드의 출력을 포함할 때 유용합니다.

기본적으로 d8은 자바 바이트 코드를 최적화된 DEX 파일로 컴파일하고 런타임 중에 코드를 디버그하는 데 사용할 수 있는 디버그 정보를 포함합니다. 그러나 증분 빌드를 실행하고 기본 DEX 파일로 컴파일해야 하는 클래스를 지정하며 자바 8 언어 기능을 사용하는 데 필요한 추가 리소스 경로를 지정하는 등의 작업을 위해 선택적 플래그를 포함할 수 있습니다.

d8 path-to-input-files [options]

다음 표에서는 d8과 함께 사용할 수 있는 선택적 플래그를 설명합니다.

옵션 설명
--debug 디버그 기호 표 등 디버그 정보를 포함하도록 DEX 바이트 코드를 컴파일합니다.

이 옵션은 기본적으로 사용 설정됩니다. DEX 바이트 코드에 디버그 정보를 포함하기 위해 d8은 입력 자바 바이트 코드에 디버그 정보가 포함되어 있다고 예상합니다. 예를 들어 javac를 사용하여 코드를 컴파일한다면 -g 플래그를 전달하여 출력 자바 바이트 코드에 디버그 정보를 포함해야 합니다.

앱의 출시 버전 또는 라이브러리용 DEX 파일을 컴파일하는 경우에는 아래에 설명된 --release 플래그를 대신 사용하세요.

--release 디버그 정보 없이 DEX 바이트 코드를 컴파일합니다. 그러나 d8에는 스택 트레이스를 생성하고 예외를 로깅할 때 사용되는 정보가 포함되어 있습니다.

공개 버전용 바이트 코드를 컴파일할 때 이 플래그를 전달해야 합니다.

--output path 원하는 DEX 출력의 경로를 지정합니다. 기본적으로 d8은 DEX 파일을 현재 작업 디렉터리에 출력합니다.

ZIP 또는 JAR 파일의 경로와 이름을 지정하면 d8은 지정된 파일을 만들고 출력 DEX 파일을 포함합니다. 기존 디렉터리의 경로를 지정하면 d8에서 그 디렉터리의 DEX 파일을 출력합니다.

--lib android_sdk/platforms/api-level/android.jar Android SDK의 android.jar 경로를 지정합니다. 이 플래그는 자바 8 언어 기능을 사용하는 바이트 코드를 컴파일할 때 필요합니다.
--classpath path d8에서 프로젝트의 DEX 파일을 컴파일하는 데 필요할 수 있는 클래스 경로 리소스를 지정합니다. 특히 d8에서는 자바 8 언어 기능을 사용하는 바이트 코드를 컴파일할 때 특정 리소스를 지정해야 합니다.
--min-api number 출력 DEX 파일이 지원할 최소 API 수준을 지정합니다.
--intermediate 이 플래그를 전달하여 프로젝트의 자바 바이트 코드 전체 세트를 컴파일하지 않는다고 d8에 알립니다. 이 플래그는 기기에서 실행될 것으로 예상하는 최적화된 DEX 파일을 컴파일하는 대신 증분 빌드를 실행할 때 유용합니다. d8은 중간 DEX 파일을 만들어 지정된 출력 또는 기본 경로에 저장합니다.

기기에서 실행하려는 DEX 파일을 컴파일하려면 이 플래그를 제외하고 중간 DEX 클래스의 경로를 입력으로 지정하세요.

--file-per-class 각 클래스를 별도의 DEX 파일로 컴파일합니다.

이 플래그를 사용 설정하면 변경된 클래스만 다시 컴파일하여 증분 빌드를 더 실행할 수 있습니다. Android Gradle 플러그인을 사용하여 증분 빌드를 실행하는 경우 이 최적화가 기본적으로 사용 설정됩니다.

--main-dex-list도 지정하면서 이 플래그를 사용할 수는 없습니다.

--no-desugaring 자바 8 언어 기능을 사용 중지합니다. 자바 8 언어 기능을 사용하는 자바 바이트 코드를 컴파일하지 않으려는 경우에만 이 플래그를 사용하세요.
--main-dex-list path d8에서 기본 DEX 파일에 포함해야 하는 클래스가 나열된 텍스트 파일을 지정합니다. 보통 이 파일의 이름은 classes.dex입니다. 즉, 이 플래그를 사용하여 클래스 목록을 지정하지 않으면 d8은 어떤 클래스가 기본 DEX 파일에 포함되어 있는지 보장하지 않습니다.

앱을 시작할 때 Android 시스템이 기본 DEX 파일을 먼저 로드하기 때문에 이 플래그를 사용하여 시작 시 특정 클래스를 기본 DEX 파일로 컴파일하여 우선순위를 정할 수 있습니다. 이 옵션은 기존 멀티덱스 라이브러리가 로드될 때까지 런타임에 기본 DEX 파일의 클래스만 사용할 수 있기 때문에 기존 멀티덱스를 지원하는 경우 특히 유용합니다.

각 DEX 파일은 여전히 64K 참조 제한을 충족해야 합니다. 따라서 기본 DEX 파일에 너무 많은 클래스를 지정하지 마세요. 너무 많은 클래스를 지정하면 컴파일 오류가 발생합니다. 기본적으로 --main-dex-list를 사용하여 클래스를 지정하면 d8에는 이러한 클래스만 기본 DEX 파일에 포함됩니다. 이에 따라 기본 DEX 파일에서 누락된 클래스와 관련된 문제를 더 쉽게 디버그할 수 있습니다. --release 모드를 지정하면 d8에서는 64K 제한에 도달할 때까지 최대한 많은 다른 클래스를 기본 DEX 파일에 포함하여 앱의 출시 버전으로 패키징된 DEX 파일의 수를 줄이려고 합니다.

--file-per-class도 지정하면서 이 플래그를 사용할 수는 없습니다.

--version 현재 사용하는 d8의 버전을 출력합니다.
--help d8 사용을 위한 도움말 텍스트를 출력합니다.

증분 빌드 실행

지속적 통합 빌드의 경우와 같이 개발하는 동안 빌드 속도를 향상하기 위해 d8에서 프로젝트의 자바 바이트 코드 하위 집합만 컴파일하도록 할 수 있습니다. 예를 들어 클래스당 덱싱을 사용 설정하면 이전 빌드 이후에 수정한 클래스만 다시 컴파일할 수 있습니다.

다음 명령어는 클래스의 증분 빌드를 실행하고 클래스당 덱싱을 사용 설정합니다. 증분 빌드를 위한 출력 디렉터리도 지정합니다.

d8 MainActivity.class R.class --intermediate --file-per-class --output ~/build/intermediate/dex

d8은 증분 빌드를 실행할 때 나중에 --main-dex-list 옵션을 올바르게 처리하고 앱의 전체 빌드 중에 DEX 파일을 병합하는 데 사용하는 DEX 출력에 추가 정보를 저장합니다. 예를 들어 자바 8 람다 클래스를 처리하는 경우 d8은 어떤 람다 클래스가 각 입력 클래스에 만들어지는지 계속 추적합니다. 전체 빌드 중에 d8에서 기본 DEX 파일에 클래스를 포함한다면 메타데이터를 참조하여 이 클래스에 만들어진 모든 람다 클래스가 기본 DEX 파일에도 포함되어 있는지 확인합니다.

이미 여러 증분 빌드에 걸쳐 프로젝트의 모든 바이트 코드를 DEX 파일로 컴파일한 경우 아래와 같이 중간 DEX 파일의 디렉터리를 d8에 전달하여 전체 빌드를 실행할 수 있습니다. 또한 --main-dex-list를 사용하여 d8이 기본 DEX 파일로 컴파일할 클래스를 지정할 수 있습니다. 이미 DEX 바이트 코드로 컴파일된 파일의 집합이 입력이므로 이 빌드는 클린 빌드보다 더 빠르게 완료됩니다.

d8 ~/build/intermediate/dex --release --main-dex-list ~/build/classes.txt --output ~/build/release/dex

자바 8 언어 기능을 사용하는 바이트 코드 컴파일

d8을 사용하면 디슈가링이라고 하는 컴파일 프로세스를 통해 코드에서 자바 8 언어 기능을 사용할 수 있습니다. 디슈가링은 이러한 유용한 언어 기능을 Android 플랫폼에서 실행할 수 있는 바이트 코드로 변환합니다.

Android 스튜디오와 Android Gradle 플러그인에는 d8에서 디슈가링을 사용 설정하는 데 필요한 클래스 경로 리소스가 포함되어 있습니다. 그러나 명령줄에서 d8을 사용할 때는 이 리소스를 직접 포함해야 합니다.

이러한 리소스 중 하나는 타겟 Android SDK의 android.jar입니다. 이 리소스에는 Android 플랫폼 API의 집합이 포함되며 --lib 플래그를 사용하여 경로를 지정합니다.

또 다른 리소스는 현재 DEX 바이트 코드로 컴파일하지 않지만 다른 클래스를 DEX 바이트 코드로 컴파일하는 데 필요한 프로젝트의 컴파일된 자바 바이트 코드 집합입니다. 예를 들어 코드에서 자바 8 언어 기능인 기본 및 정적 인터페이스 메서드를 사용하는 경우 프로젝트의 모든 자바 바이트 코드를 DEX 바이트 코드로 컴파일하지 않더라도 이 플래그를 사용하여 프로젝트의 모든 자바 바이트 코드의 경로를 지정해야 합니다. d8에서 프로젝트의 코드를 이해하고 인터페이스 메서드 호출을 확인하는 데 이 정보가 필요하기 때문입니다.

다음 코드 샘플에서는 기본 인터페이스 메서드에 액세스하는 클래스의 증분 빌드를 실행합니다.

d8 MainActivity.class --intermediate --file-per-class --output ~/build/intermediate/dex
--lib android_sdk/platforms/api-level/android.jar
--classpath ~/build/javac/debug