Precaución: Desde agosto de 2021, todos los nuevos las apps se deben publicar como paquetes de aplicación. Si publicas tu app en Google Play, compilar y subir un Android App Bundle Cuándo lo haces, Google Play genera y publica automáticamente APK optimizados para la configuración del dispositivo de cada usuario, de modo que solo descarguen el código y los recursos que necesitan para ejecutar la app. Publicar múltiples APK es útil si estás en una tienda que no admite el formato AAB. En ese caso, debes compilar, firmar y administrar cada APK por tu cuenta.
Aunque es mejor compilar un solo APK que admita todos los dispositivos de destino siempre que sea posible, podría generar un APK muy grande debido a la cantidad de archivos admite varias densidades de pantalla o objetos binarios de la aplicación Interfaces (ABI). Una forma de reducir el tamaño del APK es crear varios APK que contienen archivos para ABI o densidades de pantalla específicas.
Gradle puede crear APK separados que solo contengan el código y los recursos específicos de cada densidad o ABI. En esta página, se describe cómo configurar tu compilación a fin de generar varios APK. Si necesitas crear diferentes versiones de tu app que no se basen en una densidad de pantalla ni en ABI, usa variantes de compilación en su lugar.
Cómo configurar tu compilación para varios APK
A fin de configurar tu compilación para varios APK, agrega un bloque splits
a tu archivo build.gradle
a nivel del módulo. En el
Bloque splits
, proporciona
un bloque density
que especifica cómo quieres que Gradle genere
APK por densidad o un bloque abi
que especifique cómo quieres que Gradle
para generar APKs por ABI. Puedes proporcionar bloques de ABI y densidad.
el sistema de compilación crea un APK para cada combinación de ABI y densidad.
Cómo configurar varios APK para densidades de pantalla
Para crear APK independientes para diferentes densidades de pantalla, agrega un
bloque density
en tu
Bloque splits
. En tu bloque density
, proporciona un
lista de densidades de pantalla deseadas y tamaños de pantalla compatibles. Usar solo la lista de
tamaños de pantalla compatibles si necesitas
Elementos <compatible-screens>
en el manifiesto de cada APK.
Las siguientes opciones de Gradle DSL se usan a fin de configurar varios APK para densidades de pantalla:
-
enable
para Groovy,isEnable
para la secuencia de comandos de Kotlin -
Si configuras este elemento en
true
, Gradle generará varios APK. según las densidades de pantalla que definas. El valor predeterminado esfalse
-
exclude
-
Especifica la lista de densidades, separadas por comas, que no deseas que Gradle
para generar APKs por separado. Usa
exclude
si quieres generar APK para la mayoría de las densidades, pero necesitas excluir algunos de densidades que tu app no admite. -
reset()
-
Borra la lista predeterminada de densidades de pantalla. Solo debe usarse junto con el
include
para especificar las densidades que quieras agregar.En el siguiente fragmento, se configura la lista de densidades
ldpi
yxxhdpi
llamando areset()
para borrar la lista y, luego, usainclude
:reset() // Clears the default list from all densities // to no densities. include "ldpi", "xxhdpi" // Specifies the two densities to generate APKs // for.
-
include
-
Especifica la lista de densidades, separadas por comas, que deseas que genere Gradle.
APK de. Solo se usa junto con
reset()
para especificar un una lista exacta de densidades. -
compatibleScreens
-
Especifica la lista de tamaños de pantalla compatibles separados por comas. Esto incorpora un coincidente
<compatible-screens>
en el manifiesto de cada APK.Este parámetro de configuración ofrece una forma práctica de administrar ambas funciones densidades y tamaños de pantalla en la misma sección de
build.gradle
. Sin embargo,<compatible-screens>
puede limitar los tipos de dispositivos funciona con tu app. Para encontrar formas alternativas de admitir diferentes tamaños de pantalla, consulta la descripción general de la compatibilidad de pantallas.
Como cada APK basado en una densidad de pantalla incluye una
Etiqueta <compatible-screens>
con restricciones específicas
sobre qué tipos de pantallas admite el APK, incluso si publicas varias
APK: Algunos dispositivos nuevos no coinciden con tus filtros de varios APK. Por lo tanto,
Gradle siempre genera un APK universal adicional que contiene recursos.
para todas las densidades de pantalla y no incluye un
<compatible-screens>
. Publicar esto
APK universal junto con los APK por densidad para proporcionar un resguardo
dispositivos que no coinciden con los APK con una
<compatible-screens>
.
En el siguiente ejemplo, se genera un APK separado para cada
pantalla
densidad, excepto ldpi
, xxhdpi
y
xxxhdpi
Para ello, se usa exclude
para quitar
esas tres densidades de la lista
predeterminada de todas las densidades.
Groovy
android { ... splits { // Configures multiple APKs based on screen density. density { // Configures multiple APKs based on screen density. enable true // Specifies a list of screen densities you don't want Gradle to create multiple APKs for. exclude "ldpi", "xxhdpi", "xxxhdpi" // Specifies a list of compatible screen size settings for the manifest. compatibleScreens 'small', 'normal', 'large', 'xlarge' } } }
Kotlin
android { ... splits { // Configures multiple APKs based on screen density. density { // Configures multiple APKs based on screen density. isEnable = true // Specifies a list of screen densities you don't want Gradle to create multiple APKs for. exclude("ldpi", "xxhdpi", "xxxhdpi") // Specifies a list of compatible screen size settings for the manifest. compatibleScreens("small", "normal", "large", "xlarge") } } }
Para obtener más detalles sobre cómo personalizar diferentes compilaciones variantes de tu app para tipos de pantalla y dispositivos específicos, consulta Declaración de restricciones compatibilidad de pantalla.
Cómo configurar varios APK para las ABI
A fin de crear APK separados para diferentes ABI, agrega un bloque abi
dentro de tu bloque splits
. En el bloque abi
, proporciona una lista de
las ABI deseadas.
Las siguientes opciones de Gradle DSL se usan para configurar varios APKs por ABI:
-
enable
para Groovy oisEnable
para la secuencia de comandos de Kotlin - Si configuras este elemento en
true
, Gradle generará varias APK basados en las ABI que definas. El valor predeterminado esfalse
. -
exclude
-
Especifica la lista de las ABI, separadas por comas, que no deseas que Gradle.
generar APKs por separado para ellos. Usa
exclude
si quieres generar APK para la mayoría de las ABI, pero debes excluir aquellas que tu app no excluye y asistencia. -
reset()
-
Borra la lista predeterminada de ABI. Solo debe usarse junto con el
include
para especificar las ABI que quieres agregar.En el siguiente fragmento, se configura la lista de ABI solo en
x86
yx86_64
llamando areset()
para borrar la lista. Luego, usainclude
:reset() // Clears the default list from all ABIs to no ABIs. include "x86", "x86_64" // Specifies the two ABIs we want to generate APKs for.
-
include
-
Especifica la lista de las ABI, separadas por comas, de las que quieres que Gradle genere los APK.
. Usa esta opción solo en combinación con
reset()
para especificar un valor exacto lista de ABI. -
universalApk
para Groovy oisUniversalApk
para Secuencia de comandos de Kotlin -
Si es
true
, Gradle generará un APK universal además del APK por ABI. Un APK universal contiene el código y los recursos para todas las ABI de una un solo APK. El valor predeterminado esfalse
.Ten en cuenta que esta opción solo es disponible en el bloque
splits.abi
. Cuando compilas varios APK según la densidad de la pantalla, Gradle siempre genera un APK universal contiene código y recursos para todas las densidades de pantalla.
En el siguiente ejemplo, se genera un APK separado para cada ABI: x86
y x86_64
. Para ello, se usa reset()
.
para comenzar con una lista vacía de ABI, seguida de include
con un
de las ABI de las que cada una obtiene un APK.
Groovy
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. enable true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include "x86", "x86_64" // Specifies that you don't want to also generate a universal APK that includes all ABIs. universalApk false } } }
Kotlin
android { ... splits { // Configures multiple APKs based on ABI. abi { // Enables building multiple APKs per ABI. isEnable = true // By default all ABIs are included, so use reset() and include to specify that you only // want APKs for x86 and x86_64. // Resets the list of ABIs for Gradle to create APKs for to none. reset() // Specifies a list of ABIs for Gradle to create APKs for. include("x86", "x86_64") // Specifies that you don't want to also generate a universal APK that includes all ABIs. isUniversalApk = false } } }
Consulta la lista de las ABI admitidas en Compatible ABI.
Proyectos sin código nativo/C++
Para los proyectos sin código nativo/C++, el panel Build Variants tiene dos elementos: columnas: Module y Active Build Variant, como se muestra en la figura 1.
de
Figura 1: El panel Build Variants tiene dos columnas para los proyectos que no tienen
código nativo/C++.
El valor Active Build Variant del elemento módulo determina la variante de compilación que se implementa y se puede ver en el editor. Para alternar entre variantes, haz clic en la celda Active Build Variant de un módulo. y elige la variante deseada en el campo de lista.
Proyectos con código nativo/C++
Para los proyectos con código nativo/C++, el panel Build Variants tiene tres columnas: Módulo, Compilación activa Variant y Active ABI, como se muestra en la Figura 2.
Figura 2: El panel Build Variants agrega la columna Active ABI para proyectos con código nativo/C++.
El valor Active Build Variant del módulo determina la variante de compilación que se implementa y se puede ver en el editor. En el caso de los módulos nativos, el valor Active ABI determina la ABI a la que el editor usa, pero no afecta lo que se implementa.
Para cambiar el tipo de compilación o ABI, haz lo siguiente:
- Haz clic en la celda de Active Build Variant. o Active ABI.
- Elige la variante o la ABI que desees en la lista. . Se ejecuta automáticamente una nueva sincronización.
Si modificas cualquiera de las columnas de una app o un módulo de biblioteca, se aplica el cambio a todas filas dependientes.
Cómo configurar el control de versiones
De forma predeterminada, cuando Gradle genera varios APKs, cada uno de ellos tiene el mismo
la información de la versión, tal como se especifica en las secciones
Archivo build.gradle
o build.gradle.kts
. Debido a que el
Google Play Store no permite que todos tengan varios APKs para la misma app
la misma información de versión, debes asegurarte de que cada APK tenga un
versionCode
antes de subirlo a Play Store.
Puedes configurar el archivo build.gradle
a nivel del módulo para que haga lo siguiente:
anular el versionCode
para cada APK. Creando una asignación
que asigna un valor numérico único para cada ABI y densidad que configures
múltiples APK, puedes anular el código de la versión de salida con un valor que
combina el código de versión definido dentro de defaultConfig
bloque productFlavors
con el valor numérico asignado al
de densidad o ABI.
En el siguiente ejemplo, el APK para la ABI x86
obtiene un versionCode
de 2004 y la ABI x86_64
obtiene un versionCode
de 3,004.
Asignar códigos de versión en grandes incrementos, como 1,000, permite
que luego te asignen códigos de versión únicos si necesitas actualizar la app. Para
Por ejemplo, si defaultConfig.versionCode
se itera hasta 5 en un
actualización posterior, Gradle asigna un versionCode
de 2005 a
el APK de x86
y el 3005 en el APK de x86_64
.
Sugerencia: Si tu compilación incluye un APK universal, asígnale un
versionCode
, por debajo del de cualquiera de tus otros APK.
Dado que Google Play Store instala la versión de tu app que es compatible con el dispositivo objetivo y tiene el valor versionCode
más alto, asignar un versionCode
inferior al del APK universal garantiza que Google Play Store intente instalar uno de tus APK antes de recurrir al APK universal. El siguiente código de muestra
controla esto sin anular los atributos
versionCode
predeterminado.
Groovy
android { ... defaultConfig { ... versionCode 4 } splits { ... } } // Map for the version code that gives each ABI a value. ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3] // For per-density APKs, create a similar map: // ext.densityCodes = ['mdpi': 1, 'hdpi': 2, 'xhdpi': 3] import com.android.build.OutputFile // For each APK output variant, override versionCode with a combination of // ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. android.applicationVariants.all { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.each { output -> // Stores the value of ext.abiCodes that is associated with the ABI for this variant. def baseAbiVersionCode = // Determines the ABI for this variant and returns the mapped value. project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiVersionCode != null) { // Assigns the new version code to versionCodeOverride, which changes the // version code for only the output APK, not for the variant itself. Skipping // this step causes Gradle to use the value of variant.versionCode for the APK. output.versionCodeOverride = baseAbiVersionCode * 1000 + variant.versionCode } } }
Kotlin
android { ... defaultConfig { ... versionCode = 4 } splits { ... } } // Map for the version code that gives each ABI a value. val abiCodes = mapOf("armeabi-v7a" to 1, "x86" to 2, "x86_64" to 3) // For per-density APKs, create a similar map: // val densityCodes = mapOf("mdpi" to 1, "hdpi" to 2, "xhdpi" to 3) import com.android.build.api.variant.FilterConfiguration.FilterType.* // For each APK output variant, override versionCode with a combination of // abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. androidComponents { onVariants { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.forEach { output -> val name = output.filters.find { it.filterType == ABI }?.identifier // Stores the value of abiCodes that is associated with the ABI for this variant. val baseAbiCode = abiCodes[name] // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code doesn't override the version code for universal APKs. // However, because you want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiCode != null) { // Assigns the new version code to output.versionCode, which changes the version code // for only the output APK, not for the variant itself. output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0)) } } } }
Para obtener más ejemplos de esquemas de códigos de versión alternativos, consulta Cómo asignar códigos de versión.
Cómo crear varios APK
Una vez que configures el build.gradle
a nivel del módulo o
archivo build.gradle.kts
para compilar varios APK; haz clic
Compilación > Compilar APK para compilar todos los APK de la
el módulo seleccionado en el panel Project. Gradle crea los APK
Para cada densidad o ABI en la build/outputs/apk/
del proyecto
.
Gradle compila un APK de cada densidad o ABI para las que configuras varios APK. Si habilitas varios APK tanto para las densidades como para las ABI, Gradle creará un APK para cada combinación de densidad y ABI.
Por ejemplo, el siguiente
El fragmento build.gradle
permite compilar varios APK para mdpi
y
Densidades de hdpi
y también ABI de x86
y x86_64
:
Groovy
... splits { density { enable true reset() include "mdpi", "hdpi" } abi { enable true reset() include "x86", "x86_64" } }
Kotlin
... splits { density { isEnable = true reset() include("mdpi", "hdpi") } abi { isEnable = true reset() include("x86", "x86_64") } }
En el resultado de la configuración de ejemplo, se incluyen los 4 APK siguientes:
app-hdpiX86-release.apk
: Contiene el código y los recursos para La densidad dehdpi
y la ABI dex86
app-hdpiX86_64-release.apk
: Contiene el código y los recursos para La densidad dehdpi
y la ABI dex86_64
app-mdpiX86-release.apk
: Contiene el código y los recursos para La densidad demdpi
y la ABI dex86
app-mdpiX86_64-release.apk
: Contiene el código y los recursos para La densidad demdpi
y la ABI dex86_64
Al compilar varios APK basados en densidades de pantalla, Gradle siempre genera un APK universal que incluye el código y los recursos para todas las densidades, además de los APK por densidad.
Al compilar varios APK basados en
ABI, Gradle solo genera un APK que incluye código y recursos para todos
ABI si especificas universalApk true
en el
Bloque splits.abi
en tu archivo build.gradle
(para Groovy) o isUniversalApk = true
en las
Bloque splits.abi
en tu archivo build.gradle.kts
(para la secuencia de comandos de Kotlin).
Formato de nombre de archivo APK
Cuando compilas varios APK, Gradle genera nombres de archivo APK con lo siguiente: esquema:
modulename-screendensityABI-buildvariant.apk
Los componentes del esquema son los siguientes:
-
modulename
- Especifica el nombre del módulo que se está compilando.
-
screendensity
-
Si se habilitan varios APK para densidades de pantalla, especifica la pantalla
densidad del APK, como
mdpi
. -
ABI
-
Si se habilitan varios APK para la ABI, especifica la ABI del APK, como como
x86
.Si se habilitan varios APK tanto para la densidad de pantalla como para ABI, Gradle concatena el nombre de la densidad con el nombre de la ABI, por ejemplo.
mdpiX86
SiuniversalApk
está habilitado para por ABI APK, Gradle usauniversal
como la parte de la ABI del APK universal nombre de archivo. -
buildvariant
-
Especifica la variante de compilación que se está compilando, como
debug
.
Por ejemplo, si compilas un APK de densidad de pantalla mdpi
para el
versión de depuración de myApp, el nombre de archivo APK es
myApp-mdpi-debug.apk
El lanzamiento
una versión de myApp que esté configurada para compilar varios APK tanto para
mdpi
y la ABI x86
tiene el nombre de archivo APK de
myApp-mdpiX86-release.apk