Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

Acerca de Dynamic Delivery

El modelo de entrega de apps de Google Play, llamado Dynamic Delivery, usa los paquetes Android App Bundle a fin de generar y entregar APK optimizados para cada configuración de dispositivo, de manera que los usuarios puedan descargar únicamente el código y los recursos necesarios para ejecutar la app. Ya no tendrás que compilar, firmar y administrar varios APK para tener compatibilidad con diferentes dispositivos, y los usuarios deberán realizar descargas más pequeñas y optimizadas.

La mayoría de los proyectos de apps no requieren mucho esfuerzo para compilar paquetes de aplicación que admitan la entrega de APK divididos mediante Dynamic Delivery. Por ejemplo, si ya organizas el código y los recursos de tu app según convenciones establecidas, simplemente compila paquetes Android App Bundle firmados con Android Studio o con la línea de comandos, y cárgalos en Google Play. De esta forma, Dynamic Delivery es un beneficio automático.

Para admitir las características avanzadas de Dynamic Delivery, como configurar ciertas funciones de la app para que se entreguen condicionalmente o se descarguen on demand, consulta la sección sobre cómo personalizar la entrega de funciones.

Dynamic Delivery con APK divididos

Un componente fundamental de Dynamic Delivery es el mecanismo APK dividido disponible en Android 5.0 (nivel de API 21) y versiones posteriores. Los APK divididos son muy similares a los APK normales: incluyen el código de bytes DEX compilado, los recursos y un manifiesto de Android. Sin embargo, la plataforma Android puede tratar varios APK divididos instalados como una sola app. Por lo tanto, puedes instalar varios APK divididos que tengan acceso a código y recursos comunes, y aparecen como una misma app instalada en el dispositivo.

El beneficio de los APK divididos es la capacidad de dividir un APK monolítico, es decir, un APK que incluye código y recursos para todas las funciones y configuraciones de dispositivos compatibles con la app, en paquetes independientes más pequeños que se instalan en el dispositivo de un usuario según sea necesario.

Por ejemplo, un APK dividido puede incluir el código y los recursos para una función adicional que solo algunos de los usuarios necesitan, mientras que otro APK dividido incluye recursos para solo un idioma específico o una densidad de pantalla particular. Cada uno de estos APK divididos se descarga e instala cuando el usuario lo solicita o el dispositivo lo requiere.

A continuación, se describen los diferentes tipos de APK que se pueden instalar juntos en un dispositivo para formar la experiencia de app completa. En las demás secciones de esta página, aprenderás a configurar tu proyecto de app para admitir estos APK.

  • APK de base: este APK contiene código y recursos a los que pueden acceder todos los demás APK divididos y proporciona la funcionalidad básica de la app. Cuando un usuario solicita descargar tu app, este APK se descarga y se instala primero. Esto se debe a que solo el manifiesto del APK de base contiene una declaración completa de los servicios, proveedores de contenido, permisos, requisitos de versión de la plataforma y dependencias de las funciones del sistema de la app. Google Play genera el APK de base para la app a partir del módulo de app (o base) de tu proyecto. Si te interesa reducir el tamaño de descarga inicial de la app, es importante tener en cuenta que todo el código y los recursos incluidos en este módulo se incluyen en el APK de base de la app.
  • APK de configuración: cada uno de estos APK incluye bibliotecas nativas y recursos para una densidad de pantalla, arquitectura de CPU o idioma específicos. Cuando un usuario descarga la app, el dispositivo descarga e instala solo los APK de configuración correspondientes para su dispositivo. Cada APK de configuración depende de un APK de base o de un APK de función dinámica. Es decir, se descargan y se instalan junto con el APK al que proporcionan código y recursos. A diferencia de los módulos de base y funciones dinámicas, no es necesario crear un módulo independiente para los APK de configuración. Si usas las prácticas estándar para organizar recursos alternativos y específicos para cada configuración en tus módulos de base y funciones dinámicas, Google Play genera automáticamente los APK de configuración.
  • APK de funciones dinámicas: cada uno de estos APK contiene código y recursos para una función de la app que se modulariza mediante módulos de funciones dinámicas. Dynamic Delivery te permite personalizar cómo y cuándo se descarga esa función en un dispositivo. Por ejemplo, se puede usar la biblioteca de Play Core para instalar on demand los APK dinámicos después de instalar el APK de base en el dispositivo a fin de contar con funcionalidad adicional. Por ejemplo, piensa en una app de chat que descarga e instala la funcionalidad para capturar y enviar fotos únicamente cuando el usuario solicite usarla. Dado que las funciones dinámicas pueden no estar disponibles en el momento de la instalación, debes incluir el código y los recursos comunes en el APK de base. Esto significa que la función dinámica debe asumir que solo el código y los recursos del APK de base estarán disponibles durante la instalación. Google Play genera los APK de funciones dinámicas para tu app a partir de los módulos de funciones dinámicas del proyecto.

Otro ejemplo sería una app con tres módulos de funciones dinámicas y compatibilidad con diversas configuraciones de dispositivos. En la figura 1 a continuación, se ilustra un ejemplo de árbol de dependencias para los diversos APK de la app. Allí se ve que el APK de base forma la cabeza del árbol, y todos los demás APK dependen del APK de base. (Si quieres saber cómo se representan los módulos para estos APK en un Android App Bundle, consulta el formato Android App Bundle).

El APK de base forma la cabeza del árbol, y los APK de funciones dinámicas dependen de él. Los APK de configuración, que incluyen código y recursos específicos según la configuración del dispositivo para el APK de base y cada APK de funciones dinámicas forma los nodos de hoja del árbol de dependencias.

Figura 1: Árbol de dependencias para una app entregada con APK divididos

Recuerda que no necesitas crear estos APK, ya que Google Play lo hace automáticamente usando un único paquete de aplicación firmado que creas con Android Studio. Para obtener más información sobre el formato del paquete de aplicación y cómo crear uno, consulta Cómo compilar, implementar y subir Android App Bundles.

Dispositivos con Android 4.4 (nivel de API 19) y versiones anteriores

Puesto que los dispositivos con Android 4.4 (nivel de API 19) y versiones anteriores no admiten la descarga e instalación de APK divididos, Google Play entrega a esos dispositivos un solo APK, llamado APK múltiple, optimizado para la configuración del dispositivo. Es decir, los APK múltiples representan la experiencia de app completa, pero no incluyen código o recursos innecesarios, como los usados para otras densidades de pantalla y arquitecturas de CPU.

Sin embargo, sí incluyen recursos para todos los idiomas que admite la app. De esta forma, por ejemplo, los usuarios pueden cambiar la configuración de idioma preferida de la app sin tener que descargar un APK múltiple diferente.

Los APK múltiples no permiten descargar más adelante módulos de funciones dinámicas on demand. Para incluir un módulo dinámico en este APK, debes inhabilitar On-demand o habilitar Fusing al crear el módulo de funciones dinámicas.

Ten en cuenta que, con Dynamic Delivery, no necesitas crear, firmar, cargar y administrar APK para cada configuración de dispositivo compatible con tu app. Solo debes compilar y cargar un paquete de aplicación para toda la app, y Google Play se encarga del resto. Entonces, ya sea que planees o no admitir dispositivos con Android 4.4 o versiones anteriores, Dynamic Delivery proporciona un mecanismo de entrega flexible tanto para ti como para los usuarios.

Cómo modularizar tu app

La modularización de una app es el proceso de separar componentes lógicos del proyecto de app en módulos independientes.

La reorganización de la funcionalidad de tu app en estos componentes independientes requiere una evaluación cuidadosa y tiempo. Sin embargo, la modularización proporciona a tu proyecto los siguientes beneficios:

  • Desarrollo en paralelo: al separar los componentes lógicos de la app en módulos, diferentes equipos o personas de tu organización pueden ocuparse de cada módulo y trabajar en ellos con menos conflictos de fusión o interrupciones para otros equipos. Además, si usas lógica que se implementa en varias partes de la app, puedes usar módulos de biblioteca para facilitar la reutilización y encapsulación de código.
  • Mejores tiempos de compilación:: los sistemas de compilación, como Android Studio con Gradle, están optimizados para proyectos organizados en módulos. Por ejemplo, si habilitas la optimización de ejecución de proyectos en paralelo de Gradle en una estación de trabajo que incluye un procesador multinúcleo, el sistema de compilación puede compilar varios módulos en paralelo y reducir significativamente los tiempos de compilación. Cuanto más modular sea tu proyecto, más significativa será la mejora del rendimiento de la compilación.
  • Entrega de funciones personalizada: modularizar las funciones de tu app como módulos de funciones dinámicas es un requisito para aprovechar las opciones de entrega personalizada de Dynamic Delivery, como la entrega on demand, condicional e instantánea. Crear funciones dinámicas on demand requiere más esfuerzo y, posiblemente, la refactorización de la app. Por lo tanto, evalúa cuidadosamente cuáles de las funciones de la app sería mejor modularizar en funciones dinámicas para aprovechar las opciones de entrega personalizada.

La correcta modularización de tu proyecto según las funciones de la app requiere tiempo y consideración. Cuando decidas comenzar a modularizar tu app, primero debes configurar el módulo base con las propiedades necesarias para admitir funciones modulares. Luego, puedes modularizar gradualmente las funciones de la app sin modificar el comportamiento actual de la app configurando módulos de funciones dinámicas para la entrega en la instalación.

Cómo usar módulos de funciones dinámicas para la entrega personalizada

Una ventaja única de Dynamic Delivery es la capacidad de personalizar cómo y cuándo se descargan las diferentes funciones de la app en dispositivos con Android 5.0 (nivel de API 21) o versiones posteriores. Por ejemplo, para reducir el tamaño de la descarga inicial de tu app, puedes configurar ciertas funciones para que se descarguen on demand según sea necesario o solo en dispositivos que admitan ciertas capacidades, como la posibilidad de tomar fotografías o admitir funciones de realidad aumentada.

Si bien al cargar tu app como un paquete de aplicación obtienes una descarga altamente optimizada de manera predeterminada, las opciones de entrega de funciones más avanzadas y personalizables requieren una configuración adicional y la modularización de las funciones de la app mediante módulos de funciones dinámicas. Es decir, los módulos de funciones dinámicas proporcionan los componentes básicos para crear funciones modulares que puedes configurar para que se descarguen según sea necesario.

Piensa en una app que permite a los usuarios comprar y vender productos en un mercado en línea. Puedes modularizar razonablemente cada una de las siguientes funcionalidades de la app en módulos de funciones dinámicas independientes:

  • Inicio de sesión y creación de cuentas
  • Navegación por el mercado
  • Colocación de un artículo a la venta
  • Procesamiento de pagos

En la tabla que sigue se describen las diferentes opciones de entrega que admiten los módulos de funciones dinámicas y cómo se pueden usar para optimizar el tamaño de descarga inicial en el ejemplo de la app de mercado.

Opción de entrega Comportamiento Caso práctico de muestra Cómo empezar
Entrega en la instalación Los módulos de funciones dinámicas que no configuran ninguna de las opciones de entrega descritas anteriormente se descargan cuando se instala la app, de forma predeterminada. Este es un comportamiento importante porque permite adoptar gradualmente opciones de entrega avanzadas. Por ejemplo, puedes aprovechar la modularización de funciones de la app y habilitar la entrega on demand solo después de haber implementado completamente las descargas on demand usando la biblioteca de Play Core.

Además, la app puede solicitar la desinstalación de funciones más adelante. Por lo tanto, si necesitas ciertas funciones al instalar la app, pero no después de ese momento, puedes reducir el tamaño de la instalación solicitando que se quiten esas funciones del dispositivo.

Si la app tiene ciertas actividades de capacitación, como una guía interactiva sobre cómo comprar y vender artículos en el mercado, puedes incluir esa función al en la instalación de la app, de manera predeterminada.

Sin embargo, para reducir el tamaño instalado de la app, esta puede solicitar eliminar la función después de que el usuario haya completado la capacitación.

Modulariza tu app con módulos de funciones dinámicas que no configuran opciones de entrega avanzadas.

Para aprender a reducir el tamaño instalado de tu app gracias a la eliminación de ciertos módulos de funciones dinámicas que el usuario ya no necesita, consulta Cómo administrar módulos instalados.

Entrega a pedido Permite que la app solicite y descargue módulos de funciones dinámicas según sea necesario. Si solo el 20% de los usuarios de la app de mercado publican artículos para la venta, una buena estrategia para reducir el tamaño de descarga inicial para la mayoría de los usuarios es ofrecer la funcionalidad para tomar fotos, incluir una descripción del artículo y colocar un artículo para la venta como descarga on demand. Es decir, puedes configurar el módulo de funciones dinámicas para que la funcionalidad de venta de la app se descargue solo cuando un usuario muestre interés en colocar artículos para la venta en el mercado.

Además, si el usuario ya no vende artículos después de un cierto tiempo, la app puede solicitar la desinstalación de la función para reducir su tamaño instalado.

Crea un módulo de funciones dinámicas y configura la entrega on demand. La app puede usar la biblioteca de Play Core para solicitar la descarga del módulo on demand.
Entrega condicional Permite especificar ciertos requisitos del dispositivo del usuario, como funciones de hardware, configuración regional y un nivel mínimo de API, para determinar si una función modularizada se descarga cuando se instala la app. Si la app de mercado tiene alcance global, puede ser necesario admitir métodos de pago que se usan solo en ciertas regiones o países. Para reducir el tamaño inicial de descarga de la app, puedes crear módulos de funciones dinámicas independientes para procesar ciertos tipos de métodos de pago e instalarlos condicionalmente en el dispositivo del usuario en función de su configuración regional. Crea un módulo de funciones dinámicas y configura la entrega condicional.
Entrega inmediata Google Play Instant permite a los usuarios interactuar con la app sin necesidad de instalar APK en su dispositivo. En cambio, pueden experimentar la app a través del botón "Probar ahora" en Google Play Store o una URL que crees. Con esta forma de entregar contenido, es más fácil aumentar la interacción con tu app.

Con la entrega instantánea, puedes usar Google Play Instant para permitir que los usuarios experimenten al instante ciertas funciones de la app sin instalación.

Por ejemplo, un juego que incluya los primeros niveles en un módulo de funciones dinámicas liviano. Puedes habilitar al instante ese módulo para que los usuarios puedan experimentar el juego a través de un vínculo a una URL o el botón "Probar ahora", sin necesidad de instalar la app. Crea un módulo de funciones dinámicas y configura la entrega instantánea. La app puede usar la biblioteca de Play Core para solicitar la descarga del módulo on demand.

Ten en cuenta que modularizar las funciones de una app mediante módulos de funciones dinámicas es solo el primer paso. Para admitir Google Play Instant, el tamaño de descarga del módulo base de la app y una función dinámica habilitada al instante deben cumplir restricciones estrictas de tamaño. Para obtener más información, consulta Cómo habilitar experiencias instantáneas reduciendo el tamaño de la app o el juego.

Manifiesto del módulo de funciones dinámicas

Al crear un nuevo módulo de funciones dinámicas con Android Studio, el IDE incluye la mayoría de los atributos de manifiesto que el módulo requiere para comportarse como una función dinámica. Además, el sistema de compilación inserta algunos atributos en el momento de la compilación, por lo que no necesitas especificarlos ni modificarlos. En la tabla siguiente se describen los atributos de manifiesto que son importantes para los módulos de funciones dinámicas.

Atributo Descripción
<manifest
...
Este es un bloque <manifest> típico.
xmlns:dist="http://schemas.android.com/apk/distribution" Especifica un nuevo espacio de nombres XML dist: que se describe más adelante.
split="split_name" Cuando Android Studio compila el paquete de aplicación, incluye este atributo automáticamente. Por lo tanto, no debes incluir ni modificar este atributo.

Define el nombre del módulo, que la app especifica cuando solicita un módulo on demand desde la biblioteca de Play Core.

Cómo hace Gradle para determinar el valor de este atributo:

De manera predeterminada, cuando creas un módulo de funciones dinámicas con Android Studio, el IDE usa el valor especificado como nombre del módulo para identificar el módulo como un subproyecto de Gradle en el archivo de configuración de Gradle.

Cuando compilas tu paquete de aplicación, Gradle usa el último elemento del nombre de la ruta del subproyecto para insertar este atributo de manifiesto en el manifiesto del módulo. Por ejemplo, si creas un nuevo módulo de funciones dinámicas en el directorio MyAppProject/features/ y especificas "dynamic_feature1" como nombre del módulo, el IDE agrega ':features:dynamic_feature1' como subproyecto en el archivo settings.gradle. Al compilar un paquete de aplicación, Gradle inserta <manifest split="dynamic_feature1"> en el manifiesto del módulo.

android:isFeatureSplit="true | false"> Cuando Android Studio compila el paquete de aplicación, incluye este atributo automáticamente. Por lo tanto, no debes incluir ni modificar este atributo de forma manual.

Especifica que este es un módulo de funciones dinámicas. Los manifiestos en el módulo base y los APK de configuración omiten este atributo o lo configuran como false.

<dist:module Este nuevo elemento XML define atributos que determinan cómo se empaqueta y distribuye el módulo como APK.
dist:instant="true | false" Especifica si el módulo debe estar disponible a través de Google Play Instant como una experiencia instantánea.

Si tu app incluye uno o más módulos de funciones dinámicas con habilitación instantánea, también debes habilitar al instante el módulo base. Cuando usas Android Studio 3.3 o versiones posteriores, el IDE lo hace automáticamente cuando se crea un módulo de funciones dinámicas habilitado instantáneamente.

No es posible configurar este elemento XML en true mientras establece dist:onDemand="true". Sin embargo, puedes solicitar descargas on demand de las funciones dinámicas habilitadas al instante como experiencias instantáneas usando la biblioteca de Play Core. Cuando un usuario descarga e instala la app, el dispositivo descarga e instala las funciones dinámicas habilitadas al instante de la app, junto con el APK de base, de forma predeterminada.

dist:onDemand="true | false" Especifica si el módulo debe estar disponible como descarga on demand. Es decir, si este atributo se establece en true, el módulo no está disponible en el momento de la instalación, pero la app puede solicitar descargarlo más tarde.

Si este atributo se establece en false, el módulo se incluye cuando el usuario descarga e instala la app por primera vez.

Para obtener más información sobre las descargas on demand, lee acerca de los módulos de descarga con la biblioteca de Play Core.

dist:title="@string/feature_name" Especifica un título para el módulo que se mostrará al usuario. Por ejemplo, el dispositivo puede mostrar este título cuando solicita confirmación de descarga.

Debes incluir el recurso de strings para este título en el archivo module_root/src/source_set/res/values/strings.xml del módulo base.

<dist:fusing dist:include="true | false" />
</dist:module>
Especifica si se debe incluir el módulo en APK múltiples orientados a dispositivos con Android 4.4 (nivel de API 20) y versiones anteriores.

Además, cuando usas bundletool para generar APK a partir de un paquete de aplicación, solo los módulos de funciones dinámicas que establecen esta propiedad en true se incluyen en el APK universal, que es un APK monolítico que incluye código y recursos para todas las configuraciones de dispositivos que admite tu app.

<application
android:hasCode="true | false">
...
</application>
Si el módulo de funciones dinámicas no genera archivos DEX, es decir, no contiene ningún código que luego se compila en el formato de archivo DEX, haz lo siguiente (de lo contrario, puede haber errores de tiempo de ejecución):
  1. Establece android:hasCode en "false" en el manifiesto del módulo de funciones dinámicas.
  2. Agrega lo siguiente al manifiesto del módulo base:
    
        <application
          android:hasCode="true"
          tools:replace="android:hasCode">
          ...
        </application>
        

Cómo probar Dynamic Delivery

La mejor manera de probar Dynamic Delivery es a través de Google Play Store. Esto se debe a que muchos de los beneficios de Dynamic Delivery se basan en aplazar la generación, firma y entrega de APK a Play Store. Por lo tanto, independientemente de que incluyas compatibilidad básica con Dynamic Delivery cargando un paquete de aplicación o configures opciones de entrega personalizada, debes usar los siguientes métodos para probar la app con Dynamic Delivery.

  • Comparte tu app con una URL Esta es la forma más rápida de cargar tu paquete de aplicación y compartir tu app como un vínculo de Google Play Store con verificadores de confianza. Además, esta es la forma más rápida de probar opciones de entrega personalizada, como descargar funciones on demand.
  • Configura una prueba abierta, cerrada o interna Este método proporciona canales de prueba estructurados y es una buena manera de probar la versión de final de la app antes de lanzarla para usuarios externos.

Consideraciones sobre las funciones dinámicas

Si deseas publicar una app que incluya módulos de funciones dinámicas en una pista de producción, ten en cuenta las siguientes consideraciones:

  • Solo los dispositivos con Android 5.0 (nivel de API 21) y versiones posteriores admiten la descarga y la instalación de funciones dinámicas on demand. Para que la función dinámica esté disponible en versiones anteriores de Android, asegúrate de habilitar Fusion al crear un módulo de función dinámica.
  • Asegúrate de habilitar SplitCompat para que la app tenga acceso inmediato a los módulos de funciones dinámicas descargados.
  • Si el tamaño de descarga de la función dinámica es grande, la app necesita obtener la confirmación del usuario antes de poder descargar el módulo de función dinámica a un dispositivo.
  • Los módulos de funciones dinámicas no deben especificar actividades en su manifiesto con android:exported configurado en true. Esto se debe a que no hay garantía de que el dispositivo haya descargado el módulo de funciones dinámicas cuando otra app intenta iniciar la actividad. Además, tu app debe confirmar que se descarga una función dinámica antes de intentar acceder a su código y recursos. Para obtener más información, consulta Cómo administrar módulos instalados.
  • Dado que la entrega dinámica requiere que la app se publique usando un paquete de aplicación, asegúrate de tener en cuenta los problemas conocidos del paquete de aplicación.

Recursos adicionales

Para obtener más información sobre la compatibilidad con Dynamic Delivery, consulta el siguiente recurso.

Ejemplos

Codelabs

  • Tu primer Android App Bundle, un codelab que explora los principios básicos de los archivos Android App Bundle y te muestra cómo comenzar rápidamente a compilar el tuyo con Android Studio. Este codelab también explora cómo probar los paquetes de aplicación con bundletool.
  • Módulos on demand, que sirven de ayuda para crear una app que descarga e instala funciones dinámicas on demand.

Entradas de blog (en inglés)

Videos