El modelo de entrega de apps de Google Play usa paquetes Android App Bundle a fin de generar y publicar APK optimizados para la configuración del dispositivo de cada usuario, de manera que los usuarios descarguen solo el código y los recursos necesarios para ejecutar la app.
La publicación de funciones en Play usa capacidades avanzadas de los paquetes de aplicaciones, lo que permite que ciertas funciones se entreguen a tu app de manera condicional o se descarguen a pedido.
Cómo usar los módulos de funciones para la entrega personalizada
Un beneficio único de los módulos de funciones es la habilidad 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, a fin de reducir el tamaño de la descarga inicial de tu app, puedes configurar ciertas funciones para que se descarguen a pedido 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 cuando subes 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. Es decir, los módulos de funciones proporcionan los componentes básicos para crear funciones modulares que puedes configurar a fin de que se descarguen según sea necesario.
Piensa en una app que permite a los usuarios comprar y vender bienes en un mercado en línea. Puedes modularizar razonablemente cada una de las siguientes funciones de la app en módulos de funciones independientes:
- Acceso 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 y cómo se pueden usar para optimizar el tamaño de descarga inicial en el ejemplo de la aplicación de Marketplace.
Opción de entrega | Comportamiento | Caso práctico de muestra | Cómo comenzar |
---|---|---|---|
Entrega durante la instalación | Los módulos de funciones que no configuran ninguna de las opciones de entrega descritas con anterioridad se descargan de forma predeterminada cuando se instala la app. Este es un comportamiento importante porque permite adoptar de manera gradual 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 por completo 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 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 que no configuren opciones de entrega avanzadas. Para aprender a reducir el tamaño instalado de tu app gracias a la extracción de ciertos módulos de funciones 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 según sea necesario. | Si solo el 20% de los usuarios de la aplicación de Marketplace publican artículos para la venta, una buena estrategia de reducción del tamaño de descarga inicial para la mayoría de los usuarios es ofrecer la funcionalidad de tomar fotos, incluir una descripción del artículo y colocar un artículo a la venta como descarga a pedido. Es decir, puedes configurar el módulo de funciones 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 y configura la entrega a pedido. La app puede usar la biblioteca de Play Core para solicitar la descarga del módulo a pedido. |
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 aplicación de Marketplace tiene alcance global, puede ser necesario admitir formas de pago que se usan solo en ciertas regiones o países. A fin de reducir el tamaño de descarga inicial de la app, puedes crear módulos de funciones individuales para procesar ciertos tipos de formas de pago y, luego, instalarlos de forma condicional en el dispositivo de un usuario según su configuración regional registrada. | Crea un módulo de funciones y configura la entrega condicional. |
Entrega instantánea | Google Play Instant permite a los usuarios interactuar con tu app sin necesidad de instalar APK en sus dispositivos. En cambio, pueden experimentar la app a través del botón "Probar ahora" en Google Play Store o una URL que crees. Esta forma de entregar contenido hace que sea 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 liviano. Puedes habilitar al instante ese módulo para que los usuarios experimenten 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 y configura la entrega instantánea. La app puede usar la biblioteca de Play Core para solicitar la descarga del módulo a pedido.
Ten en cuenta que modularizar las funciones de tu app mediante módulos de funciones es solo el primer paso. Para admitir Google Play Instant, el tamaño de descarga del módulo base de la app y una cierta función habilitada instantáneamente deben cumplir con estrictas restricciones de tamaño. Para obtener más información, lee Cómo habilitar experiencias instantáneas reduciendo el tamaño de la app o el juego. |
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: Como se separan 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 la app como módulos de funciones es un requisito para aprovechar las opciones de entrega personalizada de la entrega de funciones de Play, como a pedido, condicional y entrega instantánea. Crear funciones a pedido requiere más esfuerzo y, posiblemente, la refactorización de la app. Por lo tanto, evalúa con cuidado cuáles de las funciones de la app convendría modularizar en módulos de funciones a fin de 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 deberás 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 mediante la configuración de los módulos de funciones para la entrega durante la instalación.
Manifiesto del módulo de funciones
Cuando creas un módulo de funciones nuevo con Android Studio, el IDE incluye la mayoría de los atributos de manifiesto que el módulo requiere para comportarse como un módulo de funciones. Además, el sistema de compilación inserta algunos atributos en el tiempo de 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.
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 forma predeterminada, cuando creas un módulo de funciones con Android Studio, el IDE usa lo que especificas como su nombre del módulo para identificar el módulo como un subproyecto de Gradle en tu Archivo de configuración de Gradle.
Cuando compilas tu paquete de aplicación, Gradle usa el último elemento de la ruta de acceso del subproyecto para insertar este atributo del manifiesto en el manifiesto del módulo. Por ejemplo, si creas un módulo de función nuevo en el directorio |
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 módulo es un módulo de función.
Los manifiestos en el módulo base y los APK de configuración omiten este atributo o lo configuran como |
<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 habilitadas instantáneamente, también debes habilitar al instante el módulo base. Si usas Android Studio 3.5 o versiones posteriores, el IDE lo hace automáticamente cuando creas un módulo de funciones habilitadas instantáneamente. No es posible configurar este elemento XML en |
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 |
<dist:fusing dist:include="true | false" />
|
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 |
<dist:delivery> |
Encapsula opciones que personalizan la entrega de los módulos, como se muestra a continuación. Ten en cuenta que en cada módulo de funciones se debe configurar solo un tipo de estas opciones de entrega personalizadas. |
<dist:install-time> |
Especifica que el módulo debe estar disponible en el momento de la instalación. Ese es el comportamiento predeterminado de los módulos de funciones que no especifican otro tipo de opción de entrega personalizada.
Para obtener más información sobre las descargas durante la instalación, consulta Cómo configurar la entrega durante la instalación. Ese nodo también puede especificar condiciones que limitan el módulo a dispositivos que cumplen con ciertos requisitos, como las funciones del dispositivo, el país del usuario o el nivel mínimo de API. Para obtener más información, consulta Cómo configurar la entrega condicional. |
<dist:removable dist:value="true | false" /> |
Si bundletool no se configura o se establece en Cuando se establece La configuración predeterminada es Nota: Esta función solo está disponible cuando usas el complemento de Gradle para Android 4.2 o cuando usas bundletool v1.0 desde la línea de comandos. |
</dist:install-time> |
|
<dist:on-demand/> |
Especifica que el módulo debe estar disponible como descarga a pedido. Es decir, el módulo no está disponible durante la instalación, pero es posible que la app solicite descargarlo más tarde.
Si deseas obtener más información sobre las descargas a pedido, consulta Cómo configurar la entrega a pedido. |
</dist:delivery> |
|
<application
|
Si el módulo de funciones no genera archivos DEX, es decir, no contiene ningún código que luego se compile en el formato de archivo DEX, debes hacer lo siguiente (de lo contrario, puedes encontrar errores en el tiempo de ejecución):
|
Cómo probar la entrega de funciones en Play
La mejor manera de probar la entrega de funciones en Play es mediante Google Play Store. Esto se debe a que muchos de los beneficios de la entrega de funciones de Play se basan en aplazar la generación, firma y publicación de APK en Play Store. Por lo tanto, si solo subes un paquete de aplicación o configuras opciones de entrega más avanzadas, debes usar los siguientes métodos para probar la app.
- Comparte tu app mediante una URL. Esta es la manera más rápida de subir tu paquete de aplicación y compartir la app como un vínculo de Google Play Store con verificadores de confianza. Además, es el método más rápido para probar opciones de publicación personalizadas, como la descarga de funciones a pedido.
- 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.
Cómo compilar un URI para un recurso
Si deseas acceder a un recurso almacenado en un módulo de funciones mediante un URI, consulta la siguiente información para aprender a generar un URI de recurso de módulo de funciones con Uri.Builder()
:
Kotlin
val uri = Uri.Builder() .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded .appendPath(resources.getResourceTypeName(resId)) .appendPath(String.format("%s:%s", resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace. resources.getResourceEntryName(resId) )) .build()
Java
String uri = Uri.Builder() .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded .appendPath(resources.getResourceTypeName(resId)) .appendPath(String.format("%s:%s", resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace. resources.getResourceEntryName(resId) )) .build().toString();
Cada parte de la ruta de acceso al recurso se construye en el tiempo de ejecución, lo que garantiza que se genere el espacio de nombres correcto después de cargar los APK divididos.
Si deseas un ejemplo de cómo se genera el URI, supongamos que tienes una app y módulos de funciones con estos nombres:
- Nombre del paquete de apps:
com.example.my_app_package
- Nombre del paquete de recursos de la función:
com.example.my_app_package.my_dynamic_feature
Si el resId
del fragmento de código anterior hace referencia a un recurso de archivos sin procesar con el nombre "my_video" en tu módulo de funciones, entonces el código de Uri.Builder()
debería generar el siguiente resultado:
android.resource://com.example.my_app_package/raw/com.example.my_app_package.my_dynamic_feature:my_video
Tu app puede usar este URI para acceder al recurso del módulo de funciones.
Para validar las rutas de acceso de tu URI, puedes usar el Analizador de APK a fin de inspeccionar el APK del módulo de funciones y determinar el nombre del paquete:
Figura 2: Usa el Analizador de APK para inspeccionar el nombre del paquete en un archivo de recursos compilado.
Consideraciones para los módulos de funciones
Con los módulos de funciones, puedes mejorar la velocidad de compilación y la de ingeniería, y personalizar ampliamente la entrega de las funciones de tu app a fin de reducir su tamaño. Sin embargo, hay algunas limitaciones y casos extremos que se deben tener en cuenta cuando se usan módulos de funciones:
- Instalar 50 módulos de funciones o más en un solo dispositivo, a través de la entrega condicional o a pedido, puede generar problemas de rendimiento. Los módulos de tiempo de instalación, que no están configurados como extraíbles, se incluyen automáticamente en el módulo base y solo se cuentan como un módulo de funciones en cada dispositivo.
- Limita la cantidad de módulos que configures como extraíbles para la entrega en el momento de la instalación a 10 o menos. De lo contrario, el tiempo de descarga e instalación de tu app podría aumentar.
- Solo los dispositivos con Android 5.0 (nivel de API 21) y versiones posteriores admiten la descarga y la instalación de funciones a pedido. Para que la función esté disponible en versiones anteriores de Android, habilita Fusing cuando crees un módulo de funciones.
- Habilita SplitCompat para que la app tenga acceso a los módulos de funciones descargados que se entregan a pedido.
- Los módulos de funciones no deben especificar actividades en su manifiesto con
android:exported
establecido entrue
. Esto se debe a que no hay garantía de que el dispositivo haya descargado el módulo de funciones cuando otra app intente iniciar la actividad. Además, tu app debe confirmar que se descarga una función antes de intentar acceder a su código y a sus recursos. Para obtener más información, consulta Cómo administrar módulos instalados. - Dado que la entrega de funciones de Play requiere que publiques tu app con un paquete de aplicación, asegúrate de tener en cuenta los problemas conocidos del paquete de aplicación.
Recursos adicionales
Si deseas obtener más información para admitir la entrega de funciones en Play, prueba el siguiente recurso.
Ejemplos
- Ejemplo de la API de PlayCore, que muestra el uso de la API de PlayCore para solicitar y descargar módulos de funciones
- Ejemplo de carga de código dinámico, que muestra tres enfoques diferentes para acceder de forma segura al código desde un módulo de funciones instalado
Codelabs
- Tu primer paquete 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.
En este codelab, también se analiza cómo probar los paquetes de aplicaciones usando
bundletool
. - Módulos a pedido, que te ayudan a crear una app que descargue y, luego, instale módulos de funciones a pedido.
Entradas de blog
- El nuevo formato de publicación y su importancia para el futuro de Android
- Nuevas funciones que ayudan a desarrollar, lanzar y expandir tu empresa en Google Play
- Últimas actualizaciones de Android App Bundle, incluida la API de idiomas adicionales
- El nuevo formato de publicación y su importancia para el futuro de Android
- La reinvención de Plaid: una historia de modularización (en inglés)
- La plataforma Sigue a Santa en Google pasará al formato Android App Bundle