Comprender y lograr la transición a Android 15 : de 4KB a 16KB, el cambio que bloquea la publicación de tus apps Flutter en Google Play

Sommaire
Desde Android 15 (API 35), Google impone un cambio silencioso pero masivo : los tamaños de página de memoria pasan de 4 KB a 16 KB en ciertas arquitecturas. Un detalle de bajo nivel... que a la larga bloqueará la publicación de muchas aplicaciones en Google Play.
1. Lo que cambia con Android 15
Históricamente, la mayoría de los dispositivos Android utilizaban una página de memoria de 4 KB. Android 15 introduce oficialmente el soporte de páginas de 16 KB en procesadores ARM v9 y en algunas variantes x86_64.
¿Por qué este cambio ?
- Rendimiento : menos fallos de página, mejor gestión de la memoria en cargas de trabajo pesadas.
- Seguridad : alineación de memoria más estricta para algunas protecciones.
- Hardware futuro : los nuevos SoC ARM imponen esta granularidad.
Consecuencia para tus apps
Los binarios nativos (archivos .so en tus APK/AAB) deben estar alineados a 16 KB, y compilados con un NDK reciente (r27+).
Aunque tu app Flutter no tenga código nativo, incluye bibliotecas nativas a través de sus dependencias (especialmente los plugins).
2. Los errores y síntomas que vas a encontrar
Aquí están los problemas típicos que enfrentan los desarrolladores de Flutter al actualizar :
Errores de compilación
checkReleaseAarMetadatacon dependencias AndroidX que exigencompileSdk 34+NDK not configured properlyounsupported page size- Compilación OK en Android 14, pero rechazada por Google Play al enviar
Errores en tiempo de ejecución
- Bloqueo al iniciar en un dispositivo Android 15 :
libflutter.so is not aligned for 16KB page size
Causas frecuentes
-
Plugins de Flutter fijados en
compileSdk 33Ej. :awesome_notifications_core,firebase_messaging, etc. → no se compilan contra Android 34+. -
Versiones de herramientas obsoletas
- Gradle < 8.6
- Android Gradle Plugin < 8.4
- JDK < 17 Estas versiones no reconocen las nuevas reglas NDK/ABI.
-
Mala propagación de las propiedades del SDK Flutter no impone automáticamente
compileSdkVersiona los plugins. Cada submódulo Gradle puede definir la suya.
Resultado : tu app apunta a Android 35, pero un plugin sigue compilando en 33 → fallo de compilación.
4. Los fundamentos a actualizar
Versiones mínimas recomendadas
| Herramienta | Versión mínima |
|---|---|
| Flutter SDK | 3.24.3 |
| Gradle wrapper | 8.7 |
| Android Gradle Plugin (AGP) | 8.6.1 |
| Kotlin | 1.9.24 |
| JDK | 17 |
| NDK | r27+ |
5. Configuración tipo compatible con Android 15
android/gradle.properties
android.useAndroidX=true
android.enableJetifier=true
flutter.minSdkVersion=23
flutter.targetSdkVersion=35
flutter.compileSdkVersion=36
org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8
android/app/build.gradle.kts
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
kotlin("android")
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
id("dev.flutter.flutter-gradle-plugin")
}
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
val minSdk = providers.gradleProperty("flutter.minSdkVersion").orNull?.toInt() ?: 23
val targetSdk = providers.gradleProperty("flutter.targetSdkVersion").orNull?.toInt() ?: 35
val compileSdk = providers.gradleProperty("flutter.compileSdkVersion").orNull?.toInt() ?: 36
android {
namespace = "com.yourcompany.yourapp"
compileSdk = compileSdk
ndkVersion = "29.0.13846066"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions { jvmTarget = "17" }
defaultConfig {
applicationId = "com.yourcompany.yourapp"
minSdk = minSdk
targetSdk = targetSdk
versionCode = flutter.versionCode
versionName = flutter.versionName
ndk {
abiFilters += listOf("arm64-v8a", "x86_64") // 64 bits only = compatible 16KB
}
}
packaging {
jniLibs.useLegacyPackaging = false
}
bundle {
language.enableSplit = false
density.enableSplit = false
abi.enableSplit = true
}
}
flutter {
source = "../.."
}
Y sobre todo : el bloque mágico
El problema : aunque configures compileSdkVersion en tu app, cada plugin de Flutter puede definir su propio compileSdkVersion en su build.gradle. Un solo plugin que permanezca en la versión 33 puede bloquear toda la compilación.
Solución : en android/build.gradle.kts, añade este bloque que fuerza a todos los subproyectos (plugins) a usar las mismas versiones :
En android/build.gradle.kts :
subprojects {
afterEvaluate {
val ext = extensions.findByName("android") ?: return@afterEvaluate
val cs = providers.gradleProperty("flutter.compileSdkVersion").orNull?.toInt()
val ts = providers.gradleProperty("flutter.targetSdkVersion").orNull?.toInt()
@Suppress("UNCHECKED_CAST")
(ext as? com.android.build.gradle.BaseExtension)?.apply {
if (cs != null) setCompileSdkVersion(cs)
defaultConfig {
if (ts != null) targetSdkVersion(ts)
}
}
}
}
¿Por qué afterEvaluate ? Porque los plugins configuran su extensión Android en diferentes momentos. Se espera a que todos los plugins hayan terminado su configuración antes de modificarlos.
Este bloque garantiza que todos tus plugins utilicen el mismo compileSdk/targetSdk que tu app, evitando conflictos de versiones.
6. Limpiar y recompilar
flutter clean
rm -rf android/.gradle ~/.gradle/caches
flutter pub upgrade
flutter build apk -v
7. Verificaciones finales
✅ La compilación pasa sin errores
✅ El APK/AAB contiene las ABI arm64-v8a y x86_64
✅ Apuntas a targetSdkVersion 35+
✅ Los binarios nativos están correctamente alineados (compatible con 16 KB)
8. En resumen : el nuevo paradigma Android 15
| Dominio | Antes (Android 14) | Ahora (Android 15) |
|---|---|---|
| Tamaño de página de memoria | 4 KB | 16 KB |
| ABIs mínimas | armeabi-v7a, arm64-v8a | arm64-v8a, x86_64 |
| NDK | r25+ | r27+ |
| JDK | 11 | 17 |
| AGP | 8.1 | 8.6 |
| compileSdk | 33 | 35/36 |
En conclusión
El paso a 16 KB de tamaño de página marca una modernización profunda del ecosistema Android, que Flutter debe seguir de cerca.
Los síntomas visibles (errores de compilación, plugins rotos, rechazos de Google Play) son en realidad señales de alineación : todo el pipeline (Gradle, AGP, NDK, plugins) debe actualizarse de manera coherente.
👉 Si tu proyecto Flutter ya está actualizado, estos pasos garantizan la compatibilidad con Android 15 y evitan futuros fallos relacionados con el hardware ARM v9.
Consejo de última hora : si no tienes tiempo para ponerte en conformidad de inmediato, se puede solicitar una prórroga de actualización a Google Play, pero no está garantizada. ¡Mejor anticiparse !
Recursos complementarios
Comentarios
Cargando...