Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

d8

d8, una herramienta de línea de comandos que Android Studio y el complemento de Gradle para Android usan para compilar el código de bytes Java de tu proyecto en el código de bytes DEX que se ejecuta en dispositivos Android, te permite usar las funciones del lenguaje Java 8 en el código de tu app.

d8 también se incluye como una herramienta independiente de las herramientas de compilación de Android 28.0.1 y versiones posteriores: android_sdk/build-tools/version/.

Uso general

d8 es fácil de usar y solo requiere una ruta de acceso al código de bytes Java compilado que deseas convertir en código de bytes DEX, como se muestra a continuación.

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

El código de bytes de entrada puede estar en cualquier combinación de contenedores o archivos *.class, como JAR, APK o ZIP. También puedes incluir archivos DEX para d8 a fin de fusionarlos en la salida DEX, lo que resulta útil cuando se incluye la salida de una compilación incremental.

De forma predeterminada, d8 compila el código de bytes Java en archivos DEX optimizados e incluye información de depuración que puedes usar para depurar tu código durante el tiempo de ejecución. Sin embargo, puedes incluir marcas opcionales para, por ejemplo, realizar una compilación incremental, especificar las clases que se deben compilar en el archivo DEX principal y especificar rutas de acceso a los recursos adicionales que se necesitan para usar las características de lenguaje Java 8.

d8 path-to-input-files [options]

En la siguiente tabla, se describen las marcas opcionales que puedes usar con d8.

Opción Descripción
--debug Compila el código de bytes DEX para incluir información de depuración, como tablas de símbolos de depuración.

Esta opción está habilitada de forma predeterminada. Para incluir información de depuración en tu código de bytes DEX, d8 espera que lo haga el código de bytes de entrada Java. Por ejemplo, si estás usando javac para compilar tu código, debes pasar la marca -g para incluir información de depuración en el código de bytes de salida Java.

Cuando compiles archivos DEX para la versión de lanzamiento de tu app o biblioteca, usa la marca --release que se describe a continuación.

--release Compila el código de bytes DEX sin información de depuración. Sin embargo, d8 incluye cierta información que se usa cuando se generan seguimientos de pila y excepciones de registro.

Deberías pasar esta marca cuando compiles el código de bytes para una versión pública.

--output path Especifica la ruta de acceso deseada para la salida DEX. De forma predeterminada, d8 genera los archivos DEX en el directorio de trabajo actual.

Si especificas una ruta de acceso y el nombre de un archivo ZIP o JAR, d8 crea el archivo especificado e incluye los archivos DEX de salida. Si especificas la ruta de acceso a un directorio existente, d8 genera los archivos DEX en ese directorio.

--lib android_sdk/platforms/api-level/android.jar Especifica la ruta de acceso a android.jar de tu SDK de Android. Esta marca es obligatoria cuando compilas el código de bytes que usa funciones del lenguaje Java 8.
--classpath path Especifica los recursos de ruta de clase que d8 puede requerir para compilar los archivos DEX de tu proyecto. En particular, d8 requiere que especifiques ciertos recursos cuando compiles el código de bytes que usa las funciones del lenguaje Java 8.
--min-api number Especifica el nivel mínimo de API que quieres que admitan los archivos DEX de salida.
--intermediate Pasa esta marca para que d8 sepa que no estás compilando el conjunto completo del código de bytes Java de tu proyecto. Esta marca es útil cuando se realizan compilaciones incrementales; en lugar de compilar archivos DEX optimizados que esperas ejecutar en un dispositivo, d8 crea archivos DEX intermedios y los almacena en la salida especificada o la ruta de acceso predeterminada.

Cuando quieras compilar archivos DEX para ejecutarlos en un dispositivo, excluye esta marca y especifica la ruta de acceso a las clases DEX intermedias como una entrada.

--file-per-class Compila cada clase en archivos DEX separados.

Habilitar esta marca te permite realizar más compilaciones incrementales volviendo a compilar solo las clases que cambiaron. Cuando realizas compilaciones incrementales con el complemento de Gradle para Android, esta optimización se habilita de forma predeterminada.

No puedes usar esta marca y especificar --main-dex-list al mismo tiempo.

--no-desugaring Inhabilita las funciones del lenguaje Java 8. Usa esta marca solamente si no tienes la intención de compilar el código de bytes Java que usa las funciones del lenguaje Java 8.
--main-dex-list path Especifica un archivo de texto que enumera las clases que d8 debe incluir en el archivo DEX principal, que normalmente se denomina classes.dex. Es decir, cuando no especificas una lista de clases con esta marca, d8 no garantiza qué clases están incluidas en el archivo DEX principal.

Debido a que el sistema Android carga primero el archivo DEX principal cuando inicias tu app, puedes usar esta marca para priorizar ciertas clases al inicio compilándolas en el archivo DEX principal. Esto es particularmente útil cuando se admite multidex heredado porque solo las clases del archivo DEX principal están disponibles en el tiempo de ejecución hasta que se carga la biblioteca multidex heredada.

Ten en cuenta que cada archivo DEX aún debe satisfacer el límite de referencia de 64 K. Por lo tanto, asegúrate de no especificar demasiadas clases para el archivo DEX principal; de lo contrario, obtendrás un error de compilación. De forma predeterminada, cuando se especifican clases que usan --main-dex-list, d8 incluye solo esas clases en el archivo DEX principal a fin de facilitar la depuración de problemas relacionados con las clases que faltan en ese archivo. Si especificas el modo --release, d8 intenta reducir la cantidad de archivos DEX que se empaquetan en la versión de lanzamiento de tu app incluyendo tantas otras clases en el archivo DEX principal como sea posible (hasta alcanzar el límite de 64 K).

No puedes usar esta marca y especificar --file-per-class al mismo tiempo.

--version Imprime la versión de d8 que estás usando actualmente.
--help Imprime texto de ayuda para usar d8.

Cómo realizar compilaciones incrementales

Para mejorar las velocidades de compilación durante el desarrollo, como para las compilaciones de integración continua, puedes indicarle a d8 que compile solamente un subconjunto del código de bytes Java de tu proyecto. Por ejemplo, si habilitas la conversión a DEX por clase, puedes volver a compilar solamente las clases que modificaste desde la compilación anterior.

El siguiente comando realiza una compilación incremental de algunas clases y habilita la conversión a DEX por clase. El comando también especifica un directorio de salida para la compilación incremental.

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

Cuando d8 realiza una compilación incremental, almacena información adicional en la salida DEX que luego usa para procesar correctamente la opción --main-dex-list y fusionar archivos DEX durante una compilación completa de tu app. Por ejemplo, durante el procesamiento de clases lambda de Java 8, d8 realiza un seguimiento de qué clases lambda se crean para cada clase de entrada. Durante una compilación completa, cuando d8 incluye una clase en el archivo DEX principal, consulta los metadatos para garantizar que todas las clases lambda creadas para esa clase también se incluyan en ese archivo.

Si ya compilaste todos los códigos de bytes de tu proyecto en archivos DEX en varias compilaciones incrementales, puedes realizar una compilación completa pasando el directorio de archivos DEX intermedios a d8, como se muestra a continuación. Además, puedes especificar las clases que deseas que d8 compile en el archivo DEX principal mediante --main-dex-list. Debido a que la entrada es un conjunto de archivos que ya está compilado en un código de bytes DEX, esta compilación debe completarse más rápido que una compilación limpia.

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

Cómo compilar el código de bytes que usa las funciones del lenguaje Java 8

d8 te permite usar las funciones del lenguaje Java 8 en tu código a través de un proceso de compilación llamado expansión de sintaxis, que convierte estas útiles funciones de lenguaje en un código de bytes que se puede ejecutar en la plataforma de Android.

Android Studio y el complemento de Gradle para Android incluyen recursos de rutas de clase que d8 requiere para habilitar la expansión de sintaxis para ti. Sin embargo, cuando usas d8 desde la línea de comandos, debes incluirlos tú mismo.

Uno de esos recursos es android.jar de tu SDK de Android objetivo. Este recurso incluye un conjunto de API de la plataforma de Android, y puedes especificar su ruta de acceso con la marca --lib.

Otro recurso es el conjunto del código de bytes Java compilado de tu proyecto que actualmente no estás compilando en el código de bytes DEX, pero que necesitas para compilar otras clases en él. Por ejemplo, si tu código usa métodos de interfaz estáticos y predeterminados, que es una función del lenguaje Java 8, necesitas usar esta marca para especificar la ruta de acceso a todo el código de bytes Java de tu proyecto, incluso si no pretendes compilarlo todo en un código de bytes DEX. Esto se debe a que d8 requiere esta información para comprender el código de tu proyecto y resolver las llamadas a los métodos de la interfaz.

En la siguiente muestra de código, se realiza una compilación incremental de una clase que accede a un método de interfaz predeterminado:

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