The Android Developer Challenge is back! Submit your idea before December 2.

AAPT2

AAPT2 (Android Asset Packaging Tool) es una herramienta de compilación que Android Studio y el Complemento Gradle para Android usan para compilar y empaquetar los recursos de tu app. Esta analiza, indexa y compila los recursos en un formato binario que está optimizado para la plataforma Android.

En el Complemento Gradle para Android 3.0.0 y versiones posteriores AAPT2 está habilitada de forma predeterminada y, por lo general, no necesitas invocar a aapt2 tú mismo. Sin embargo, si prefieres usar tu terminal y tu propio sistema de compilación en lugar de Android Studio, puedes usar AAPT2 desde la línea de comandos. También puedes depurar errores de compilación relacionados con AAPT2 desde la línea de comandos. Para ello, puedes encontrar AAPT2 como una herramienta independiente en las Herramientas de compilación del SDK de Android 26.0.2 y versiones posteriores.

Para descargar las Herramientas de compilación del SDK de Android desde la línea de comandos, usa sdkmanager y ejecuta el siguiente comando:

    sdkmanager "build-tools;build-tools-version"
    

Una vez que descargaste las Herramientas de compilación del SDK, podrás encontrar la AAPT2 en android_sdk/build-tools/version/. Como una revisión más reciente de las Herramientas de compilación del SDK de Android no se publica con mucha frecuencia, la versión de AAPT2 incluida en las Herramientas de compilación del SDK podría no ser la más reciente. Para obtener la versión más reciente de AAPT2, lee Cómo descargar AAPT2 de Google Maven.

Para usar AAPT2 desde la línea de comandos en Linux o Mac, ejecuta el comando aapt2. En Windows, ejecuta el comando aapt2.exe. AAPT2 admite una compilación más rápida de recursos al habilitar la compilación incremental, que se logra al dividir el procesamiento de recursos en dos pasos:

  • Compilación: Compila archivos de recursos en formatos binarios.
  • Vinculación: Combina todos los archivos compilados y los incluye en un solo paquete.

Esta división ayuda a mejorar el rendimiento de las compilaciones incrementales. Por ejemplo, si se realizan cambios en un solo archivo, solo necesitarás volver a compilar ese archivo.

Cómo descargar AAPT2 de Google Maven

Para obtener la versión más reciente de AAPT2 que no está incluida en las herramientas de compilación, puedes descargar AAPT2 del repositorio Maven de Google de la siguiente manera:

  1. Navega a com.android.tools.build > aapt2 en el índice del repositorio.
  2. Copia el nombre de la versión más reciente de AAPT2.
  3. Inserta el nombre de la versión que copiaste en la siguiente URL y especifica el sistema operativo de destino: https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/aapt2-version/aapt2-aapt2-version-[windows | linux | osx].jar

    Por ejemplo, si quieres descargar la versión 3.2.0-alpha18-4804415 para Windows, debes usar https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/3.2.0-alpha18-4804415/aapt2-3.2.0-alpha18-4804415-windows.jar

  4. Desde un navegador, accede a la URL; AAPT2 debería comenzar a descargarse rápidamente.

  5. Extrae el archivo JAR que acabas de descargar. Este debe contener un ejecutable aapt2 y algunas bibliotecas de las que depende el ejecutable.

Compilación

AAPT2 admite la compilación de todos los tipos de recursos de Android, como archivos de elementos de diseño y XML. Cuando invocas AAPT2 para tu compilación, debes pasar un solo archivo de recursos como entrada por invocación. Luego, AAPT2 analizará el archivo y generará un archivo binario intermedio con una extensión .flat.

Si bien puedes pasar directorios de recursos que contengan más de un archivo de recursos a AAPT2 por medio del indicador --dir, no obtendrás los beneficios de la compilación incremental de recursos cuando lo hagas. Es decir, cuando pasas directorios completos, AAPT2 vuelve a compilar todos los archivos en el directorio incluso cuando solo se modificó un recurso.

Los tipos de archivos de salida pueden diferir en función de la entrada que proporciones para la compilación. En la siguiente tabla, se proporciona una explicación:

Entrada Salida
Archivos de recursos XML, como String y Style, que se ubican en el directorio res/values/. Tabla de recursos con *.asrc.flat como su extensión.
Todos los demás archivos de recursos. Todos los otros archivos que no se incluyen en el directorio res/values/ se convierten en archivos XML binarios con extensiones *.flat. Además, todos los archivos PNG se procesan de manera predeterminada y adoptan extensiones *.png.flat . Si eliges no comprimir los archivos PNG, puedes usar la opción --no-crunch durante la compilación.

Los archivos AAPT2 no son ejecutables y, más adelante, deberás incluir estos archivos binarios como entrada en la fase de vinculación para generar un APK. Sin embargo, el archivo APK generado no es un ejecutable que podrás implementar en un dispositivo Android de inmediato, ya que no contiene archivos DEX (código de byte compilado) y no está firmado.

Sintaxis de la compilación

La sintaxis general para usar el comando compile es la siguiente:

    aapt2 compile path-to-input-files [options] -o output-directory/
    

En el siguiente ejemplo, AAPT2 compila archivos de recursos llamados values.xml y myImage.png individualmente:

    aapt2 compile project_root/module_root/src/main/res/values-en/
    strings.xml -o compiled/
    aapt2 compile project_root/module_root/src/main/res/drawable
    /myImage.png -o compiled/
    

Como se muestra en la tabla anterior, el nombre del archivo de salida depende del nombre del archivo de entrada y del nombre de su directorio principal (el tipo de recurso y la configuración). En el ejemplo anterior con strings.xml como entrada, aapt2 nombra automáticamente el archivo de salida como values-en_strings.arsc.flat. Por otro lado, el nombre de archivo para el archivo de elementos de diseño compilado que se almacena en el directorio drawable será drawable_img.png.flat.

Opciones de compilación

Hay varias opciones que puedes usar con el comando compile, como se muestra en la tabla debajo:

Opción Descripción
-o path Especifica la ruta de salida para los recursos compilados.

Este es un indicador obligatorio porque debes especificar una ruta de acceso a un directorio en el que AAPT2 pueda generar y almacenar los recursos compilados.

--dir directory Especifica el directorio para buscar recursos.

Si bien puedes usar este indicador para compilar varios archivos de recursos con un comando, este inhabilita los beneficios de la compilación incremental y, por lo tanto, no debe usarse para proyectos grandes.

--pseudo-localize Genera versiones pseudolocalizadas de strings predeterminadas, como en-XA y en-XB.
--no-crunch Inhabilita el procesamiento de PNG.

Usa esta opción si ya procesaste los archivos PNG o si estás creando compilaciones de depuración que no requieren reducción de tamaño de archivo. Si habilitas esta opción, obtendrás una ejecución más rápida, pero aumentará el tamaño del archivo de salida.

--legacy Trata como alertas los errores que son admisibles cuando se usan versiones anteriores de AAPT.

Este indicador debe usarse para errores inesperados que se producen en el tiempo de compilación. Para resolver los cambios de comportamiento conocidos que podrías experimentar cuando usas AAPT2, lee Cambios de comportamiento en AAPT2.

-v Habilita el registro detallado.

En la fase de vinculación, AAPT2 fusiona todos los archivos intermedios generados en la fase de compilación (como tablas de recursos, archivos XML binarios y archivos PNG procesados) y los empaqueta en un solo APK. Además, se pueden generar otros archivos auxiliares como R.java y archivos de reglas ProGuard durante esta fase. Sin embargo, el APK generado no contiene el código de byte DEX y no está firmado. Es decir, no puedes implementar este APK en un dispositivo. Si no estás usando el complemento Gradle para Android a fin de compilar tu app desde la línea de comandos, puedes usar otras herramientas de línea de comandos, como d8 para compilar código de byte Java en código de byte DEX y apksigner para firmar tu APK.

La sintaxis general para usar el comando link es la siguiente:

    aapt2 link path-to-input-files [options] -o
    outputdirectory/outputfilename.apk --manifest AndroidManifest.xml
    

En el siguiente ejemplo, AAPT2 fusiona los dos archivos intermedios -drawable_Image.flat y values_values.arsc.flat, y el archivo AndroidManifest.xml. AAPT2 vincula el resultado con el archivo android.jar que contiene los recursos definidos en el paquete de Android:

     aapt2 link -o output.apk
     -I android_sdk/platforms/android_version/android.jar
        compiled/res/values_values.arsc.flat
        compiled/res/drawable_Image.flat --manifest /path/to/AndroidManifest.xml -v
    

Puedes usar las siguientes opciones con el comando link:

Opción Descripción
-o path Especifica la ruta de salida para el APK del recurso vinculado.

Este es un indicador obligatorio porque debes especificar la ruta de acceso para el APK de salida que puede contener los recursos vinculados.

--manifest file Especifica la ruta de acceso al archivo de manifiesto de Android para compilar.

Este es un indicador obligatorio porque el archivo de manifiesto contiene información esencial sobre tu app, como el nombre del paquete y el ID de la app.

-I Proporciona la ruta de acceso a android.jar o a otros APK de la plataforma, como framework-res.apk, que pueden ser útiles cuando compilas funciones.

Este indicador es obligatorio si estás usando atributos con el espacio de nombres de android (por ejemplo, android:id) en tus archivos de recursos.
-A directory Especifica un directorio de recursos que se incluirá en el APK.

Puedes usar este directorio para almacenar archivos originales sin procesar. Para obtener más información, lee Cómo acceder a archivos originales.

-R file Pasa un archivo .flat individual para vincular, por medio de la semántica de overlay sin usar el indicador de etiqueta <add-resource>. .

Cuando proporcionas un archivo de recursos que se superpone (extiende o modifica) con un archivo existente, se usa el último recurso en conflicto determinado.

--package-id package-id Especifica el ID del paquete que se usará para tu app.

El ID de paquete que especifiques debe ser mayor o igual que 0x7f, a menos que se use en combinación con --allow-reserved-package-id..

--allow-reserved-package-id Permite el uso de un ID de paquete reservado.

Los ID de paquetes reservados son ID que normalmente se asignan a bibliotecas compartidas y pueden estar entre 0x02 a 0x7e inclusive. Mediante el uso de --allow-reserved-package-id, puedes asignar los ID que se encuentren dentro del rango de ID de paquetes reservados.

Solo debe usarse para paquetes con una versión min-sdk de 26 o inferior.

--java directory Especifica el directorio en el cual se debe generar R.java.
--proguard proguard_options Genera un archivo de salida de las reglas ProGuard.
--proguard-conditional-keep-rules Genera un archivo de salida de las reglas ProGuard para el DEX principal.
--no-auto-version Inhabilita control automático de versiones del SDK de diseño y estilo.
--no-version-vectors Inhabilita el control automático de versiones de elementos de diseño vectoriales. Solo debes usarlo cuando compiles tu APK con la Biblioteca de elementos de diseño vectoriales.
--no-version-transitions Inhabilita el control automático de versiones de los recursos de transición. Solo debes usarlo cuando compiles tu APK con la biblioteca de compatibilidad de transición.
--no-resource-deduping Inhabilita la eliminación automática de recursos duplicados con valores idénticos en configuraciones compatibles.
--enable-sparse-encoding Habilita la codificación de entradas dispersas por medio de un árbol binario de búsqueda, lo que resulta útil para la optimización del tamaño de APK, pero a costa del rendimiento de la recuperación de recursos.
-z Requiere la localización de las strings marcadas como "sugeridas".
-c config Proporciona una lista de opciones de configuración separadas por comas.

Por ejemplo, si tienes dependencias en la biblioteca de compatibilidad (que contiene traducciones para varios idiomas), puedes filtrar recursos solo para la configuración de idioma específica, como inglés o español.

Debes definir la configuración de idioma con un código de idioma ISO 639-1 de dos letras y, de manera opcional, seguido de un código de región ISO 3166-1-alpha-2 de dos letras precedido por "r" en minúscula (por ejemplo, en-rUS).

--preferred-density density Permite a AAPT2 seleccionar la densidad que mejor coincide y quitar todas los demás.

Hay varios calificadores de densidad de píxeles disponibles para usar en tu app, como ldpi, hdpi y xhdpi. Cuando especifiques una densidad preferida, AAPT2 seleccionará y almacenará la densidad que coincida mejor en la tabla de recursos y quitará todas las demás.

--output-to-dir Envía el contenido del APK a un directorio especificado por -o.

Si encuentras algún error con este indicador, puedes corregirlo actualizando a las Herramientas de compilación del SDK de Android 28.0.0 o versiones posteriores.

--min-sdk-version min-sdk-version Configura la versión de SDK mínima predeterminada para usar en AndroidManifest.xml.
--target-sdk-version target-sdk-version Configura la versión de SDK de destino predeterminada para usar en AndroidManifest.xml.
--version-code version-code Especifica el código de versión (número entero) para inyectar en AndroidManifest.xml si no hay ninguno presente.
--compile-sdk-version-name compile-sdk-version-name Especifica el nombre de la versión para inyectar en AndroidManifest.xml si no hay ninguno presente.
--proto-format Genera recursos compilados en formato Protobuf.

Puede usarse como entrada en la herramienta de paquete para generar un Android App Bundle.

--non-final-ids Genera R.java con ID de recursos no finales (las referencias a los ID del código de la app no se intercalarán durante la compilación de kotlinc/javac).
--emit-ids path Emite un archivo en la ruta de acceso específica con una lista de nombres de tipos de recursos y sus asignaciones de ID. Es adecuado para usar con --stable-ids.
--stable-ids outputfilename.ext Consume el archivo generado con --emit-ids que contiene la lista de nombres de tipos de recursos y sus ID asignados.

Esta opción permite que los ID asignados permanezcan estables incluso cuando borras o agregas nuevos recursos durante la vinculación.

--custom-package package_name Especifica el paquete Java personalizado en el cual se generará R.java.
--extra-packages package_name Genera el mismo archivo R.java, pero con diferentes nombres de paquetes.
--add-javadoc-annotation annotation Agrega una anotación JavaDoc a todas las clases de Java generadas.
--output-text-symbols path Genera un archivo de texto que contiene los símbolos de recursos de la clase R en el archivo especificado.

Debes especificar la ruta de acceso al archivo de salida.

--auto-add-overlay Permite la inclusión de nuevos recursos en superposiciones sin usar la etiquetas <add-resource> .
--rename-manifest-package manifest-package Cambia el nombre del paquete en AndroidManifest.xml.
--rename-instrumentation-target-package instrumentation- target-package Cambia el nombre del paquete de destino para la instrumentación.

Debe usarse junto con --rename-manifest-package..

-0 extension

Especifica las extensiones de archivos que no quieres comprimir.

--split path:config[,config[..]] Divide los recursos en función de un conjunto de opciones de configuración. para generar una versión diferente del APK.

Debes especificar la ruta de acceso al APK de salida junto con el conjunto de opciones de configuración.

-v Habilita una salida más detallada.

Volcado

dump se usa para imprimir información del manifiesto y de recursos sobre el APK generado a partir del comando link. Puedes imprimir la información en tu consola mediante dump, como se muestra a continuación:

    aapt2 dump output.apk
    

Sintaxis de volcado

La sintaxis general para usar el comando dump es la siguiente:

    aapt2 dump filename.apk [options]
    

Opciones de volcado

Puedes usar las siguientes opciones con dump:

OpciónDescripción
--no-values Suprime la salida de valores al mostrar el recurso.
--file file Especifica un archivo como argumento para que se vuelque del APK.
-v Aumenta el nivel de detalle de la salida.

Cambios de comportamiento cuando usas AAPT2

Antes de AAPT2, AAPT era la versión predeterminada de Android Asset Packaging Tool, pero ahora dejó de estar disponible. Si bien AAPT2 debería funcionar inmediatamente con proyectos antiguos, en esta sección, se describen algunos cambios de comportamiento que deberías tener en cuenta.

Jerarquías de elementos en el manifiesto de Android

En las versiones anteriores de AAPT, los elementos anidados en nodos incorrectos en el manifiesto de Android se ignoraban o generaban una alerta. Por ejemplo, considera el siguiente caso:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.example.myname.myapplication">
       <application
           ...
           <activity android:name=".MainActivity">
               <intent-filter>
                   <action android:name="android.intent.action.MAIN" />
                   <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
               <action android:name="android.intent.action.CUSTOM" />
           </activity>
       </application>
    </manifest>
    

Las versiones anteriores de AAPT simplemente ignoraban la etiqueta <action> ubicada de manera incorrecta. Sin embargo, con AAPT2, verás el siguiente error:

    AndroidManifest.xml:15: error: unknown element <action> found.
    

Para solucionar el problema, asegúrate de que tus elementos de manifiestos se aniden correctamente. Para obtener más información, lee Estructura del archivo de manifiesto.

Declaración de recursos

Ya no puedes indicar el tipo de un recurso desde el atributo name. Por ejemplo, en el siguiente caso se declara de manera incorrecta un elemento de recurso attr:

    <style name="foo" parent="bar">
        <item name="attr/my_attr">@color/pink</item>
    </style>
    

Declarar un tipo de recurso de esta manera da como resultado el siguiente error de compilación:

    Error: style attribute 'attr/attr/my_attr (aka my.package:attr/attr/my_attr)'
    not found.
    

Para corregir este error, debes declarar explícitamente el tipo mediante type="attr":

    <style name="foo" parent="bar">
      <item type="attr" name="my_attr">@color/pink</item>
    </style>
    

Además, cuando se declara un elemento <style>, su elemento superior también deberá ser un tipo de recurso de estilo. De lo contrario, verás un error similar al siguiente:

    Error: (...) invalid resource type 'attr' for parent of style
    

Espacio de nombres de Android con ForegroundLinearLayout

ForegroundLinearLayout incluye tres atributos: foregroundInsidePadding, android:foreground y android:foregroundGravity. Ten en cuenta que foregroundInsidePadding no se incluye en el espacio de nombres de android, a diferencia de los otros dos atributos.

En versiones anteriores de AAPT, el compilador ignoraba de manera silenciosa los atributos foregroundInsidePadding cuando se definían con el espacio de nombres de android. Si se usa AAPT2, el compilador los detecta de inmediato y muestra el siguiente error de compilación:

    Error: (...) resource android:attr/foregroundInsidePadding is private
    

Para resolver este problema, simplemente reemplaza android:foregroundInsidePadding por foregroundInsidePadding.

Uso incorrecto de símbolos de referencia del recurso @

AAPT2 muestra errores de compilación cuando omites o incluyes de manera incorrecta los símbolos de referencia del recurso (@). Por ejemplo, si omites el símbolo cuando se especifica un atributo de estilo, como se muestra a continuación:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
      ...
      <!-- Note the missing '@' symbol when specifying the resource type. -->
      <item name="colorPrimary">color/colorPrimary</item>
    </style>
    

Cuando se compila el módulo, AAPT2 muestra el siguiente error de compilación:

    ERROR: expected color but got (raw string) color/colorPrimary
    

Ocurre lo mismo si incluiste el símbolo de manera incorrecta cuando accediste a un recurso desde el espacio de nombres de android, como se muestra a continuación:

    ...
    <!-- When referencing resources from the 'android' namespace, omit the '@' symbol. -->
    <item name="@android:windowEnterAnimation"/>
    

Cuando se compila el módulo, AAPT2 muestra el siguiente error de compilación:

    Error: style attribute '@android:attr/windowEnterAnimation' not found
    

Configuración incorrecta de bibliotecas

Si tu app depende de una biblioteca de terceros que se creó con versiones anteriores de las Herramientas de compilación del SDK de Android, esta podría fallar durante el tiempo de ejecución sin mostrar ningún error o alerta. Esta falla podría producirse porque, durante la creación de la biblioteca, los campos de R.java se declaran como final y, como resultado, todos los ID de recursos se intercalan en las clases de la biblioteca.

AAPT2 se basa en la capacidad de volver a asignar los ID a los recursos de biblioteca cuando compilas tu app. Si la biblioteca asume que los ID son final y los tiene intercalados en la biblioteca DEX, se producirá un error de coincidencia durante el tiempo de ejecución.

Para corregir este error, ponte en contacto con el autor de la biblioteca a fin de volver a compilarla con la versión más reciente de las Herramientas de compilación del SDK de Android y vuelve a publicarla.