Compilar y lanzar una aplicación para Android
Cómo prepararse para y lanzar una aplicación de Android en la Play store.
Para probar una aplicación, puedes usar flutter run en la línea de comandos,
o las opciones Run y Debug en tu IDE.
Cuando estés listo para preparar una versión de lanzamiento de tu aplicación, por ejemplo para publicar en Google Play Store, esta página puede ayudarte. Antes de publicar, es posible que quieras dar algunos toques finales a tu aplicación. Esta guía explica cómo realizar las siguientes tareas:
- Añadir un icono de lanzamiento
- Habilitar Material Components
- Firmar la aplicación
- Reducir tu código con R8
- Habilitar soporte para multidex
- Revisar el manifiesto de la aplicación
- Revisar la configuración de compilación
- Compilar la aplicación para su lanzamiento
- Publicar en Google Play Store
- Actualizar el número de versión de la aplicación
- Preguntas frecuentes sobre lanzamientos en Android
Añadir un icono de lanzamiento
#Cuando se crea una nueva aplicación Flutter, tiene un icono de lanzamiento predeterminado. Para personalizar este icono, es posible que desees consultar el paquete flutter_launcher_icons.
Alternativamente, puedes hacerlo manualmente siguiendo estos pasos:
-
Revisa las directrices de iconos de productos de Material Design para el diseño de iconos.
-
En el directorio
[project]/android/app/src/main/res/, coloca tus archivos de iconos en carpetas nombradas usando calificadores de configuración. Las carpetas predeterminadasmipmap-demuestran la convención de nomenclatura correcta. -
En
AndroidManifest.xml, actualiza el atributoandroid:iconde la etiquetaapplicationpara hacer referencia a los iconos del paso anterior (por ejemplo,<application android:icon="@mipmap/ic_launcher" ...). -
Para verificar que el icono haya sido reemplazado, ejecuta tu aplicación e inspecciona el icono de la aplicación en el Launcher.
Habilitar Material Components
#Si tu aplicación utiliza platform views, es posible que desees habilitar Material Components siguiendo los pasos descritos en la guía de inicio rápido para Android.
Por ejemplo:
- Añade la dependencia de Material de Android en
<my-app>/android/app/build.gradle.kts:
dependencies {
// ...
implementation("com.google.android.material:material:<version>")
// ...
}
dependencies {
// ...
implementation 'com.google.android.material:material:<version>'
// ...
}
Para conocer la última versión, visita Google Maven.
-
Establece el tema claro en
<my-app>/android/app/src/main/res/values/styles.xml:xml<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar"> <style name="NormalTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> -
Establece el tema oscuro en
<my-app>/android/app/src/main/res/values-night/styles.xml:xml<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar"> <style name="NormalTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
Firmar la aplicación
#Para publicar en la Play Store, debes firmar tu aplicación con un certificado digital.
Android utiliza dos claves de firma: upload (de subida) y app signing (de firma de la aplicación).
- Los desarrolladores suben un archivo
.aabo.apkfirmado con una upload key a la Play Store. - Los usuarios finales descargan el archivo
.apkfirmado con una clave de firma de la aplicación.
Para crear tu clave de firma de la aplicación, utiliza Play App Signing como se describe en la documentación oficial de la Play Store.
Para firmar tu aplicación, sigue las siguientes instrucciones.
Crear un almacén de claves (keystore) de subida
#Si tienes un keystore existente, salta al siguiente paso. Si no, crea uno utilizando uno de los siguientes métodos:
-
Ejecuta el siguiente comando en la línea de comandos:
En macOS o Linux, usa el siguiente comando:
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA \ -storetype JKS -keysize 2048 -validity 10000 -alias uploadEn Windows, usa el siguiente comando en PowerShell:
keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks ` -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 ` -alias uploadEste comando almacena el archivo
upload-keystore.jksen tu directorio personal. Si deseas almacenarlo en otro lugar, cambia el argumento que pasas al parámetro-keystore. Sin embargo, mantén el archivokeystoreprivado; ¡no lo subas al control de código fuente público!
Referenciar el keystore desde la aplicación
#Crea un archivo llamado [project]/android/key.properties
que contenga una referencia a tu keystore.
No incluyas los corchetes angulares (< >).
Indican que el texto sirve como un marcador de posición para tus valores.
storePassword=<password-from-previous-step>
keyPassword=<password-from-previous-step>
keyAlias=upload
storeFile=<keystore-file-location>
El storeFile podría estar ubicado en
/Users/<nombre de usuario>/upload-keystore.jks en macOS
o C:\\Users\\<nombre de usuario>\\upload-keystore.jks en Windows.
Configurar la firma en Gradle
#Al compilar tu aplicación en modo release, configura Gradle para usar tu clave de subida.
Para configurar Gradle, edita el archivo <project>/android/app/build.gradle.kts.
-
Define y carga el archivo de propiedades del keystore antes del bloque de propiedad
android. Establece el objeto
keystorePropertiespara cargar el archivokey.properties.
import java.util.Properties
import java.io.FileInputStream
plugins {
...
}
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
...
}
import java.util.Properties
import java.io.FileInputStream
plugins {
...
}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
...
}
- Añade la configuración de firma antes del bloque de propiedades
buildTypesdentro del bloque de propiedadesandroid.
android {
// ...
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now,
// so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
signingConfig = signingConfigs.getByName("release")
}
}
...
}
android {
// ...
signingConfigs {
release {
keyAlias = keystoreProperties['keyAlias']
keyPassword = keystoreProperties['keyPassword']
storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword = keystoreProperties['storePassword']
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now,
// so `flutter run --release` works.
signingConfig = signingConfigs.debug
signingConfig = signingConfigs.release
}
}
...
}
Flutter ahora firma todas las compilaciones de lanzamiento.
Para obtener más información sobre cómo firmar tu aplicación, consulta Firma tu aplicación en la documentación para desarrolladores de Android.
Firma híbrida de criptografía poscuántica (PQC) (Android 17+)
#Android 17 presenta el esquema de firma de APK v3.2. Este esquema combina firmas clásicas (como RSA o EC) con firmas ML-DSA para permitir la firma híbrida de criptografía poscuántica (PQC). Esto protege la identidad de firma de tu aplicación de cara al futuro frente a la amenaza potencial de ataques que utilicen la computación cuántica.
- Aplicaciones que utilizan Play App Signing: Si utilizas Play App Signing, puedes esperar a que Google Play te dé la opción de actualizar a una firma híbrida utilizando una clave PQC generada por Google Play.
- Aplicaciones que utilizan claves autogestionadas:
Si gestionas tus propias claves de firma,
puedes utilizar herramientas de compilación de Android actualizadas (como
apksigner) para migrar a una identidad híbrida, combinando una clave PQC con una nueva clave clásica. Ten en cuenta que debes crear una nueva clave clásica; no puedes reutilizar la antigua.
Para obtener más información, consulta la documentación de Android sobre la firma de APK con PQC
Reducir tu código con R8
#R8 es el nuevo reductor de código de Google.
Está habilitado de forma predeterminada cuando compilas un APK o AAB de lanzamiento.
Para deshabilitar R8, pasa la opción --no-shrink a
flutter build apk o flutter build appbundle.
Habilitar soporte para multidex
#Al escribir aplicaciones grandes o hacer uso de plugins grandes,
es posible que encuentres el límite dex de Android de 64k métodos
cuando tu objetivo es una API mínima de 20 o inferior.
Esto también puede ocurrir al ejecutar versiones de depuración de tu aplicación
usando flutter run que no tienen habilitada la reducción.
La herramienta Flutter admite habilitar multidex fácilmente.
La forma más sencilla es optar por el soporte de multidex cuando se te solicite.
La herramienta detecta errores de compilación de multidex y
pregunta antes de realizar cambios en tu proyecto de Android.
Optar por participar permite que Flutter dependa automáticamente de
androidx.multidex:multidex y use un
FlutterMultiDexApplication generado como la aplicación del proyecto.
Cuando intentas compilar y ejecutar tu aplicación con las opciones Run y Debug en tu IDE, tu compilación podría fallar con el siguiente mensaje:
Para habilitar multidex desde la línea de comandos,
ejecuta flutter run --debug y selecciona un dispositivo Android:
Cuando se te solicite, ingresa y.
La herramienta Flutter habilita el soporte multidex y vuelve a intentar la compilación:
También puedes optar por admitir multidex manualmente siguiendo las guías de Android y modificando la configuración del directorio de Android de tu proyecto. Se debe especificar un archivo keep de multidex que incluya:
io/flutter/embedding/engine/loader/FlutterLoader.class
io/flutter/util/PathUtils.class
Además, incluye cualquier otra clase utilizada en el inicio de la aplicación. Para obtener una guía más detallada sobre cómo agregar soporte de multidex manualmente, consulta la documentación oficial de Android.
Revisar el manifiesto de la aplicación
#Revisa el archivo predeterminado del Manifiesto de la aplicación (App Manifest).
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="[project]"
...
</application>
...
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Verifica los siguientes valores:
| Etiqueta | Atributo | Valor |
|---|---|---|
application
|
Edita el
android:label
en la etiqueta
application
para reflejar el nombre final de la aplicación. |
|
uses-permission
|
Añade el valor de
android.permission.INTERNET
permission
al atributo
android:name
si tu aplicación necesita acceso a Internet. La plantilla estándar no incluye esta etiqueta, pero permite el acceso a Internet durante el desarrollo para habilitar la comunicación entre las herramientas de Flutter y una aplicación en ejecución. |
Revisar la configuración de compilación de Gradle
#Para verificar la configuración de compilación de Android,
revisa el bloque android en el
script de compilación de Gradle predeterminado.
El script de compilación de Gradle predeterminado se encuentra en [project]/android/app/build.gradle.kts.
android {
namespace = "com.example.[project]"
// Any value starting with "flutter." gets its value from
// the Flutter Gradle plugin.
// To change from these defaults, make your changes in this file.
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
...
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.[project]"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
buildTypes {
...
}
}
ID de la aplicación
#El applicationId es el identificador único para tu aplicación en la Google Play Store
y en los dispositivos de los desarrolladores.
Si actualizas las propiedades applicationId y namespace,
también debes actualizar la declaración de package en tu archivo MainActivity.kt
o MainActivity.java y mover el archivo
a la estructura de directorios correspondiente.
Por ejemplo:
- En Kotlin, si tu nuevo ID es
com.example.myapp, mueve tu archivoMainActivityaandroid/app/src/main/kotlin/com/example/myapp/MainActivity.kty asegúrate de que la primera línea seapackage com.example.myapp. - En Java, mueve tu archivo
MainActivityaandroid/app/src/main/java/com/example/myapp/MainActivity.javay asegúrate de que la primera línea seapackage com.example.myapp.
Versiones del SDK de Android
#Las herramientas de Flutter establecen valores predeterminados para las versiones del SDK de Android:
compileSdk: La versión del SDK de Android utilizada para compilar la aplicación.minSdk: La versión mínima de Android que admite la aplicación.targetSdk: La versión de Android en la que la aplicación está diseñada y probada para ejecutarse.
Estos valores predeterminados (flutter.compileSdkVersion, etc.) son gestionados por Flutter
para garantizar la compatibilidad con el framework y los plugins.
Normalmente no necesitas cambiar estos a menos que:
- Necesites una API más nueva: Si estás utilizando un plugin o una característica que requiere un
minSdkmás alto que el valor predeterminado de Flutter, puedes establecerlo manualmente en un número de versión superior (por ejemplo,minSdk = 24). - Necesites bloquear versiones: Si deseas evitar actualizaciones automáticas de estas versiones al actualizar Flutter, puedes reemplazar las variables predeterminadas con valores enteros específicos.
Código y nombre de la versión
#El versionCode y el versionName se configuran automáticamente desde tu archivo pubspec.yaml
(usando el campo version: 1.0.0+1). Generalmente no necesitas modificar estos en el archivo Gradle.
Compilar la aplicación para su lanzamiento
#Tienes dos formatos de lanzamiento posibles cuando publicas en la Play Store.
- App bundle (preferido)
- APK
Compilar un app bundle
#Esta sección describe cómo compilar un app bundle de lanzamiento. Si completaste los pasos de firma, la aplicación bundle estará firmada. En este punto, podrías considerar ofuscar tu código de Dart para que sea más difícil de aplicar ingeniería inversa. Ofuscar tu código implica agregar opciones a tu comando de compilación y mantener archivos adicionales para desofuscar los stack traces.
Desde la línea de comandos:
- Ingresa
cd [project] - Ejecuta
flutter build appbundle
(Ejecutarflutter buildpor defecto realiza una compilación de lanzamiento).
El bundle de lanzamiento para tu aplicación se crea en
[project]/build/app/outputs/bundle/release/app.aab.
De forma predeterminada, el app bundle contiene tu código de Dart y el Flutter runtime compilado para armeabi-v7a (ARM de 32 bits), arm64-v8a (ARM de 64 bits) y x86-64 (x86 de 64 bits).
Probar el app bundle
#Un app bundle se puede probar de varias maneras. Esta sección describe dos.
Fuera de línea usando la herramienta bundletool
#- Si aún no lo has hecho, descarga
bundletooldesde su repositorio de GitHub. - Genera un conjunto de APK a partir de tu app bundle.
- Despliega los APK en los dispositivos conectados.
En línea usando Google Play
#- Sube tu bundle a Google Play para probarlo. Puedes usar el canal de pruebas internas, o los canales alfa o beta para probar el bundle antes de lanzarlo en producción.
- Sigue los pasos para subir tu bundle a la Play Store.
Compilar un APK
#Aunque se prefieren los app bundles sobre los APK, hay tiendas que aún no admiten app bundles. In este caso, compila un APK de lanzamiento para cada ABI (Application Binary Interface) de destino.
Si completaste los pasos de firma, el APK estará firmado. En este punto, podrías considerar ofuscar tu código de Dart para que sea más difícil de aplicar ingeniería inversa. Ofuscar tu código implica agregar opciones a tu comando de compilación.
Desde la línea de comandos:
Ingresa
cd [project].-
Ejecuta
flutter build apk --split-per-abi. (El comandoflutter buildpor defecto realiza una compilación--release).
Este comando da como resultado tres archivos APK:
[project]/build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk[project]/build/app/outputs/flutter-apk/app-arm64-v8a-release.apk[project]/build/app/outputs/flutter-apk/app-x86_64-release.apk
Eliminar la opción --split-per-abi da como resultado un APK fat que contiene
tu código compilado para todos los ABI de destino.
Estos APK son más grandes que sus equivalentes divididos,
lo que hace que el usuario descargue binarios nativos que
no corresponden a la arquitectura de su dispositivo.
Cuando se usan APK divididos, el framework agrega ABI_VERSION * 1000
al código de versión. Esto se debe a que la Google Play Store
no permite
que múltiples APK para la misma aplicación tengan el mismo código de versión.
Para forzar el código de versión predeterminado, especifica la opción
-P force-version-code-ignoring-abi=true durante la compilación.
Instalar un APK en un dispositivo
#Sigue estos pasos para instalar el APK en un dispositivo Android conectado.
Desde la línea de comandos:
- Conecta tu dispositivo Android a tu computadora con un cable USB.
- Ingresa
cd [project]. - Ejecuta
flutter install.
Publicar en Google Play Store
#Para obtener instrucciones detalladas sobre cómo publicar tu aplicación en la Google Play Store, consulta la documentación de lanzamiento en Google Play.
Actualizar el número de versión de la aplicación
#El número de versión predeterminado de la aplicación es 1.0.0.
Para actualizarlo, navega al archivo pubspec.yaml
y actualiza la siguiente línea:
version: 1.0.0+1
El número de versión consta de tres números separados por puntos,
como 1.0.0 en el ejemplo anterior,
seguido de un número de compilación opcional,
como 1 en el ejemplo anterior, separado por un +.
Tanto la versión como el número de compilación se pueden anular en
la compilación de Flutter especificando --build-name y --build-number, respectivamente.
En Android, build-name se usa como versionName mientras que
build-number se usa como versionCode. Para obtener más información,
consulta Versiona tu aplicación
en la documentación de Android.
Cuando reconstruyes la aplicación para Android, cualquier actualización en
el número de versión desde el archivo pubspec actualizará
el versionName y el versionCode en el archivo local.properties.
Preguntas frecuentes sobre lanzamientos en Android
#Aquí tienes algunas preguntas frecuentes sobre el despliegue de aplicaciones de Android.
¿Cuándo debería compilar app bundles en lugar de APK?
#La Google Play Store recomienda que despliegues app bundles en lugar de APK porque permiten una entrega más eficiente de la aplicación a tus usuarios. Sin embargo, si estás distribuyendo tu aplicación por otros medios que no sean la Play Store, un APK podría ser tu única opción.
¿Qué es un APK fat (completo)?
#Un APK fat es un único APK que contiene binarios para múltiples
ABI incrustados en él. Esto tiene el beneficio de que el único APK
se ejecuta en múltiples arquitecturas y, por lo tanto, tiene una compatibilidad más amplia,
pero tiene el inconveniente de que el tamaño de su archivo es mucho mayor,
lo que hace que los usuarios descarguen y almacenen más bytes al instalar
tu aplicación. Al compilar APK en lugar de app bundles,
se recomienda encarecidamente compilar APK divididos,
como se describe en compilar un APK usando la
opción --split-per-abi.
¿Cuáles son las arquitecturas de destino compatibles?
#Al compilar tu aplicación en modo release, las aplicaciones de Flutter se pueden compilar para armeabi-v7a (ARM de 32 bits), arm64-v8a (ARM de 64 bits) y x86-64 (x86 de 64 bits).
¿Cómo firmo el app bundle creado por flutter build appbundle?
#
Consulta Firmar la aplicación.
¿Cómo compilo un lanzamiento desde Android Studio?
#En Android Studio, abre la carpeta android/
existente bajo la carpeta de tu aplicación. Luego,
select build.gradle (Module: app) en el panel del proyecto:
A continuación, selecciona la variante de compilación. Haz clic en Build > Select Build Variant en el menú principal. Selecciona cualquiera de las variantes en el panel Build Variants (debug es la opción predeterminada):
Los archivos de app bundle o APK resultantes se encuentran en
build/app/outputs dentro de la carpeta de tu aplicación.
¿Cómo saber si un APK usa Flutter?
#Puedes usar la herramienta apkanalyzer
y listar los archivos:
apkanalyzer files list --files-only <SOME-APK> files list --files-only <SOME-APK>
Luego busca un archivo en /lib/<ARCH>/libflutter.so.
Por ejemplo, lo siguiente debería devolver un número mayor que 0:
apkanalyzer files list some-flutter-app.apk | grep flutter.so | wc -l
Why this works
Flutter depende del código C++ utilizado por el motor de Flutter. En Android,
este código se incluye con el framework de Flutter y el código Dart del
desarrollador como una biblioteca nativa llamada libflutter.so.
Las herramientas de Java/Android renombran la biblioteca flutter con el prefijo lib
y manejan la ubicación de la biblioteca a través de las arquitecturas.
Así es como algunos aplican ingeniería inversa a un APK para identificarlo como una aplicación Flutter.
Evaluación secundaria:
#Ejecuta apkanalyzer manifest print <SOME-APK> y busca una etiqueta <meta-data>
con android:name="flutterEmbedding".
El valor puede ser 1 o 2.
Ejemplo:
apkanalyzer manifest print some-flutter-app.apk | grep flutterEmbedding -C 2
devuelve una cadena con el siguiente estilo.
<meta-data
android:name="flutterEmbedding"
android:value="2" />
Why this works
Flutter ha tenido dos embedders diferentes,
y esta opción se leía para determinar qué embedder se utilizaba.
Flutter 3.22
eliminó la posibilidad de compilar aplicaciones con el embedder v1.
Este mecanismo no es recomendado porque no está
claro cuánto tiempo continuará incluyéndose el valor flutterEmbedding
en todas las aplicaciones de Flutter.
Además, esto no funcionará para todas las bibliotecas escritas
en Flutter que se importan en aplicaciones de Android como dependencias AAR.
Evaluación no técnica
#- Descarga Flutter Shark en un dispositivo y permite que escanee las aplicaciones locales.
- Visita el sitio web de Flutter Hunt.
A menos que se indique lo contrario, la documentación en este sitio refleja Flutter 3.44.0. Página actualizada por última vez el 26-06-2026. Ver código fuente oreportar un problema.