Migra tu app instantánea para admitir Android App Bundles

Si todavía usas el complemento de funciones obsoleto de Gradle para Android (com.android.feature) en módulos de Apps instantáneas Android, deberás comenzar a usar el complemento de base de la app (com.android.application) y el de funciones dinámicas (com.android.dynamic-feature).

En el complemento de Gradle para Android 3.3.0 y versiones posteriores, el complemento de base de la app incluye compatibilidad con experiencias instantáneas. Es decir, si el módulo de base de la app cumple con los requisitos de una experiencia instantánea, obtendrás automáticamente ese beneficio. Luego tendrás la posibilidad de incluir funciones adicionales que los usuarios podrán descargar a pedido, como experiencias instantáneas, utilizando el complemento de funciones dinámicas. Esta configuración facilita la compatibilidad de las apps instaladas y las instantáneas desde un solo proyecto, y te permite obtener los beneficios de publicar con Android App Bundles.

En la siguiente tabla, se describen con más detalles los complementos a los que migrarás:

Descripción del módulo Complemento anterior Complemento actual
Es el módulo que incluye el código básico, los recursos y la funcionalidad para la experiencia de app instalada o instantánea. com.android.feature (con baseFeature = true) com.android.application

Nota: Este módulo incluye toda la información del manifiesto y de firmas necesaria para compilar y empaquetar la app como un Android App Bundle o APK.

Son las funciones modulares adicionales que los usuarios pueden descargar a pedido. com.android.feature com.android.dynamic-feature (con dist:instant="true" y dist:onDemand="false" en el manifiesto del módulo)
Son los códigos y los recursos de una función disponible solo en la versión instalada de la app. com.android.application com.android.dynamic-feature (con dist:instant="false" y dist:onDemand="false" en el manifiesto del módulo)

En esta página se muestra cómo debes migrar el proyecto de app instantánea existente para crear el Android App Bundle de una aplicación instantánea, además de cómo compilar, probar y publicar esos recursos.

Si estás creando nuevas experiencias instantáneas para tu app, lee Cómo crear un módulo de funciones compatibles con apps instantáneas.

Cómo entender los cambios

Cuando migras un proyecto para utilizar el complemento de funciones dinámicas, los Android App Bundles proporcionan una nueva forma de compilar y publicar la app que simplifica en gran medida la distribución de APK optimizados a los usuarios.

Los paquetes de aplicaciones simplifican la distribución porque empaquetan todo el código compilado de la app y los recursos para la carga, pero posponen la generación del APK y la firma en Google Play. El nuevo modelo de entrega de apps de Google Play usa el paquete de aplicación para generar y entregar APK optimizados para la configuración del dispositivo de cada usuario, de manera que solo descarguen el código y los recursos necesarios para ejecutar la app. Ya no tendrás que compilar, firmar ni administrar múltiples APK para admitir diferentes dispositivos, y los usuarios podrán realizar descargas más pequeñas y optimizadas.

Cuando se usaba el complemento de funciones que ahora es obsoleto para compilar una app instantánea, era necesario crear un módulo de función básica que incluyera el código y los recursos compartidos por todos los módulos, incluido el de la app instantánea. Se incluía el resto del código en varios módulos de funciones no básicas, que contenían puntos de entrada para las experiencias instantáneas. En el caso de la versión instalada de una app, el proyecto podía incluir un módulo de app separado, que contenía el código y las actividades necesarias solo para la app instalada.

Cuando migras una app para que sea compatible con Android App Bundles, el módulo de la aplicación recupera la función del módulo de base y organiza experiencias adicionales, ya sean instaladas o instantáneas, como módulos de funciones. Es decir, ahora el proyecto se parece más al de una app estándar, con un módulo de base de aplicación instantánea y la capacidad de incluir experiencias instantáneas modulares adicionales.

Para migrar un proyecto de app instantánea existente y adoptar el modelo de distribución optimizada de Android App Bundle, sigue los pasos que se describen en las próximas secciones.

Cómo convertir el módulo de funciones básicas en uno de app

Primero, debes editar el archivo build.gradle del módulo de función básica, antes de convertirlo en el módulo de la app principal, de la siguiente manera:

  1. Borra la línea baseFeature true.
  2. Quita toda dependencia que use las configuraciones de dependencias de feature o application.

    Groovy

    dependencies {
        ...
        // delete any lines that look like
        // feature project(":foo")
        // feature project(":bar")
        // application project(":app")
    }
    

    Kotlin

    dependencies {
        ...
        // delete any lines that look like
        // feature(project(":foo"))
        // feature(project(":bar"))
        // application(project(":app"))
    }
    
  3. Mueve el applicationId, junto con cualquier otra configuración de secuencias de comandos de compilación que esperarías tener en el módulo de base de la app, del módulo com.android.application actual a com.android.feature. A continuación, se muestran algunos ejemplos. Para este paso, según la configuración específica de build.gradle, podría ser más fácil copiar y pegar el bloque android del build.gradle correspondiente al módulo de la app anterior en el archivo build.gradle del módulo de la app nueva. Sin embargo, debes proceder con precaución.

    Groovy

    android {
        ...
        defaultConfig {
            // You need to move the application ID from the app module
            // to your feature module.
            applicationId "com.example.myapp"
            ...
        }
        // Some additional build configurations you might want to
        // copy from your current ‘app’ module may include ProGuard
        // rules and code shrinking settings.
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile(
                  'proguard-android-optimize.txt'),
                  'proguard-rules.pro'
            }
        }
    }
    

    Kotlin

    android {
        ...
        defaultConfig {
            // You need to move the application ID from the app module
            // to your feature module.
            applicationId = "com.example.myapp"
            ...
        }
        // Some additional build configurations you might want to
        // copy from your current ‘app’ module may include ProGuard
        // rules and code shrinking settings.
        buildTypes {
            getByName("release") {
                minifyEnabled = true
                proguardFiles(
                    getDefaultProguardFile("proguard-android-optimize.txt"),
                    "proguard-rules.pro"
                )
            }
        }
    }
    
  4. Para marcar el módulo de funciones como de app instantánea, agrega las etiquetas de distribución de paquetes apropiadas en el manifiesto, como se muestra a continuación.

    <manifest ... xmlns:dist="http://schemas.android.com/apk/distribution">
        <dist:module dist:instant="true" />
        ...
    </manifest>
    
  5. Para convertir el módulo de funciones en el módulo de base de la app, cambia el tipo de complemento a com.android.application:

    Groovy

    // Replace  "plugins { id 'com.android.feature' }"
    // with the following
    plugins {
      id 'com.android.application'
    }
    

    Kotlin

    // Replace  "plugins { id("com.android.feature") }"
    // with the following
    plugins {
        id("com.android.application")
    }
    

Cómo convertir el módulo de app anterior en un módulo de funciones durante la instalación

Si no tienes código ni recursos en el módulo anterior, puedes borrarlo porque los pasos que seguiste en la sección anterior convirtieron el módulo de funciones en el módulo de base de la app.

Sin embargo, si tienes código y recursos en el módulo de la app anterior que representan la funcionalidad que quisieras que estuviera disponible para los usuarios cuando instalen la app, sigue los pasos de esta sección a fin de convertir el módulo de la app en un módulo de funciones.

La creación de un módulo de funciones implica cambiar el tipo de complemento de com.android.application a com.android.dynamic-feature, junto con algunos otros cambios de build.gradle, como se muestra a continuación:

  1. Cambia el tipo de complemento de com.android.application a com.android.dynamic-feature.

    Groovy

    // Replace "plugins { id 'com.android.feature' }"
    // with the following:
    plugins {
      id 'com.android.dynamic-feature'
    }
    

    Kotlin

    // Replace "plugins { id("com.android.application") }"
    // with the following:
    plugins {
        id("com.android.dynamic-feature")
    }
    
  2. Como se describió en la sección anterior, debes asegurarte de haber transferido las configuraciones de compilación requeridas por el complemento com.android.application al módulo de base de la app, así como las reglas applicationId o proguardFiles.

  3. Cambia el nombre del módulo por uno similar a "installed_feature", de la siguiente manera:

    1. Abre el panel Project seleccionando View > Tool Windows > Project en la barra de menú.
    2. Haz clic con el botón derecho en el módulo de funciones y selecciona Refactor > Rename.
    3. En el cuadro de diálogo que aparece, selecciona Rename module y haz clic en OK.
    4. Ingresa el nuevo nombre del módulo y haz clic en OK.
  4. Al igual que en el paso 3, cambia el nombre del módulo de la app nueva que creaste en la sección anterior por uno como "app".

  5. Agrega una dependencia de implementación en el módulo "app", en el archivo build.gradle del módulo de funciones, como se muestra a continuación.

    Groovy

    dependencies {
        ...
        // In the feature module, add an implementation dependency
        // on the base app module.
        implementation project(":app")
    }
    

    Kotlin

    dependencies {
        ...
        // In the feature module, add an implementation dependency
        // on the base app module.
        implementation(project(":app"))
    }
    
  6. Agrega la función en el archivo build.gradle del nuevo módulo de la app.

    Groovy

    android {
        ...
        // In the base app module, specify each feature module.
        dynamicFeatures = [":installed_feature"]
    }
    

    Kotlin

    android {
        ...
        // In the base app module, specify each feature module.
        dynamicFeatures.addAll(listOf(":installed_feature"))
    }
    
  7. En el manifiesto del módulo de funciones, marca ese módulo como instalable agregando las etiquetas de distribución de paquetes apropiadas.

    <manifest ... xmlns:dist="http://schemas.android.com/apk/distribution">
        <dist:module dist:instant="false" dist:onDemand="false"
                dist:title="@string/title_dynamic_feature">
            <dist:fusing dist:include="true" />
        </dist:module>
        ...
    </manifest>
    

Cómo convertir otros módulos de funciones en módulos de funciones compatibles con apps instantáneas

Si dividiste funcionalidades adicionales de la app en varios módulos de funciones, debes seguir los pasos de esta sección para convertirlos en módulos de funciones compatibles con apps instantáneas.

Procede de la siguiente manera para convertir cada módulo de funciones restante del proyecto en funciones compatibles con apps instantáneas:

  1. Cambia el tipo de complemento del archivo build.gradle a com.android.dynamic-feature, como se muestra a continuación:

    Groovy

    // Replace 'com.android.feature' with 'com.android.dynamic-feature'
    plugins {
      id 'com.android.dynamic-feature'
    }
    

    Kotlin

    // Replace "com.android.feature" with "com.android.dynamic-feature"
    plugins {
        id("com.android.dynamic-feature")
    }
    
  2. Marca cada módulo de funciones como compatible con apps instantáneas agregando lo siguiente al manifiesto.

    <manifest ... xmlns:dist="http://schemas.android.com/apk/distribution">
        <dist:module dist:instant="true" dist:onDemand="false"
                dist:title="@string/title_dynamic_feature">
            <dist:fusing dist:include="true" />
        </dist:module>
        ...
    </manifest>
    
  3. Agrega el módulo de funciones al archivo build.gradle del nuevo módulo de la aplicación en el que agregaste installed_feature a la lista de módulos de funciones.

    Groovy

    android {
       ...
       dynamicFeatures = [":installed_feature", ":feature_1", ":feature_2"]
       // or whichever name exists for the instant enabled feature module
    }
    

    Kotlin

    android {
       ...
       dynamicFeatures.addAll(listOf(":installed_feature", ":feature_1", ":feature_2"))
       // or whichever name exists for the instant enabled feature module
    }
    

Cómo compilar, probar y publicar un nuevo paquete de apps instantáneas

Después de completar los pasos de esta página, el proyecto generará un solo artefacto (un Android App Bundle), que podrás usar para publicar tanto la versión instalada de la app como la instantánea en Google Play Console y lanzarlas de forma separada en los segmentos de apps instantáneas o instaladas. Además, los paquetes de aplicaciones te permiten publicar APK optimizados para la configuración del dispositivo de cada usuario, por lo que estos descargarán solo el código y los recursos que necesiten para ejecutar la app. Es decir, ya no tendrás que compilar, firmar ni administrar varios APK para tener compatibilidad con diferentes dispositivos, y los usuarios realizarán descargas más pequeñas y optimizadas.

Para comenzar a compilar y probar un paquete de app instantánea, consulta Cómo compilar el paquete de aplicación.