La migración de Android a páginas de memoria de 16 KB: qué se rompe de verdad y cómo revisar tu APK
Google ahora exige que las apps de Android admitan páginas de memoria de 16 KB. Esto es lo que significa en la práctica, por qué las bibliotecas nativas son las que se rompen y cómo verificar que la tuya está a salvo.
Si tu app incluye código nativo — tu propio JNI, o simplemente un SDK de terceros que trae un archivo .so — es muy probable que esté cargando una mina que solo estalla en hardware más nuevo. Android ahora admite páginas de memoria de 16 KB además de las tradicionales de 4 KB, y Google Play exige que las apps orientadas a versiones recientes de Android funcionen correctamente con ambas. La mayoría de las apps hechas solo en Kotlin pasan esto sin ningún cambio. Las apps con dependencias nativas, a menudo no, y el modo de fallo es feo: no es una advertencia de lint, es un cierre inesperado al instalar o en el primer arranque, solo en los dispositivos que realmente usan páginas de 16 KB.
Pasé por esta migración en toda la suite de apps — la mayor parte no fue ningún problema, excepto una dependencia que sí lo fue. Esto es lo que implica de verdad la revisión.
Por qué importa el tamaño de página
Una página de memoria es la unidad más pequeña con la que el sistema operativo gestiona la memoria. Android ha usado páginas de 4 KB desde el principio; algunos chips más recientes usan páginas de 16 KB por defecto, porque las páginas más grandes reducen la sobrecarga de gestionar memoria en cargas de trabajo intensivas en RAM — menos entradas en la tabla de páginas, menos fallos de TLB, arranques de app en promedio más rápidos. El sistema operativo y el Android Runtime manejan esto de forma transparente para el código Kotlin y Java normal. Es invisible para ViewModel, Room, Compose — a nada de eso le importa el tamaño de página subyacente.
Al código nativo sí le importa, porque las bibliotecas nativas son binarios ELF, y los binarios ELF tienen sus segmentos cargables alineados a un límite fijo en tiempo de compilación. Un .so compilado con segmentos alineados a 4 KB funciona bien en un dispositivo de páginas de 4 KB. Carga ese mismo archivo en un dispositivo que corre páginas de 16 KB, y el enlazador dinámico puede no mapearlo correctamente — la app no arranca, o falla en el momento en que toca esa biblioteca.
Qué se rompe de verdad
Tu código Kotlin no. La lista de riesgo real es corta y concreta:
- Tus propios módulos NDK/JNI, si compilas alguno.
- AAR de terceros que incluyen bibliotecas nativas precompiladas — procesamiento de imágenes, reporte de fallos, motores de base de datos, runtimes de ML. Cualquier cosa con un
.sodentro de su AAR es candidata. - Salida de una cadena de herramientas antigua. Una biblioteca compilada con un NDK más antiguo, antes de que la cadena de herramientas alineara por defecto los segmentos a 16 KB, es el caso de fallo más común, incluso en un SDK que por lo demás recibe mantenimiento activo — el binario simplemente no se ha recompilado desde que cambió el valor por defecto de alineación.
Lo que no se rompe: las dependencias puramente en Kotlin, cualquier cosa distribuida solo como .jar o .aar sin código nativo, y las bibliotecas propias de Google en sus versiones recientes, ya recompiladas con la alineación correcta.
Revisar qué hay realmente en tu APK
Antes de tocar la configuración de compilación, averigua si estás expuesto de verdad:
unzip -l app-release.apk | grep '\.so$'
Si eso no devuelve nada, ya está — no hay código nativo que alinear. Si devuelve entradas, revisa directamente la alineación de segmentos de cada biblioteca:
unzip -p app-release.apk lib/arm64-v8a/libsomething.so | \
readelf -l - | grep LOAD
Mira la columna Align de cada segmento LOAD. 0x4000 (16 KB) significa que esa biblioteca ya está correctamente alineada. 0x1000 (4 KB) significa que no lo está, y es la que tienes que perseguir — ya sea una versión actualizada del SDK del que viene, o una recompilación si es tu propio código.
El APK Analyzer de Android Studio muestra la misma información sin necesidad de la línea de comandos: abre el APK, entra en un archivo .so bajo lib/, y marca directamente la alineación limitada a 4 KB.
La solución, en orden de cuánto control tienes
- Tu propio código nativo: recompílalo con un NDK actual. Las versiones recientes de la cadena de herramientas producen por defecto una salida alineada a 16 KB, así que a menudo es solo subir de versión en
build.gradle.ktsmás una recompilación limpia — sin cambios en el código fuente. - Un SDK de terceros con un
.soantiguo: actualiza la dependencia. Casi todos los SDK con mantenimiento activo ya publicaron una compilación alineada a 16 KB; la solución es subir de versión, no un parche. - Una dependencia que no se ha actualizado: este es el caso incómodo. Tus opciones reales son abrir un issue contra el SDK, hacer un fork y recompilar si es de código abierto, o eliminar la dependencia. No existe ningún truco a nivel de APK que realinee un
.soque no compilaste tú.
La biblioteca que me atrapó fue exactamente el caso 2 — una extensión de base de datos que traía binarios nativos precompilados para el cifrado en reposo detrás del historial de transacciones de Granyn. Una actualización menor de versión trajo la compilación alineada; nada cambió en el código de integración.
Probar en un dispositivo real de 16 KB
Las comprobaciones de alineación te dicen qué debería pasar; probar en páginas reales de 16 KB te dice qué pasa de verdad. El Emulador de Android incluye imágenes de sistema construidas específicamente para esto — busca una variante “16 KB Page Size” de un nivel de API reciente en el SDK Manager, crea un AVD a partir de ella e instala tu APK exactamente como lo harías para una versión de producción. Si algo que usa una biblioteca mal alineada va a fallar, fallará ahí, de inmediato y de forma reproducible, que es un lugar mucho mejor para encontrarlo que un ticket de soporte desde un dispositivo que no tienes.
Lo que hay que llevarse
Para la mayoría de las apps centradas en Kotlin, esta migración es invisible — sin código nativo, sin exposición, nada que hacer. Para cualquier cosa que traiga dependencias nativas, la solución es casi siempre subir la versión de la dependencia en lugar de reescribir: encuentra el .so mal alineado con readelf, actualiza lo que lo trajo, recompila y verifica en una imagen de sistema de 16 KB antes de publicar. La revisión toma diez minutos. Saltársela significa enterarte por un reporte de fallos en su lugar.
// Lecturas relacionadas
Más del diario
La API In-App Review de Android: pedir una valoración sin resultar molesto
Una guía práctica de la API In-App Review de Google: cómo funciona realmente, cuándo activarla y por qué el típico popup de 'valóranos' está perjudicando en silencio tu puntuación en Play Store.
App shortcuts y Quick Settings Tiles en Android: registrar agua sin abrir la app
Una guía práctica de la API dinámica ShortcutManager y de TileService en Android — cómo hacer que una acción de un solo toque se salte la app por completo, con los errores en los que caen la mayoría de las implementaciones.
Tipos de servicio en primer plano en Android en 2026: elegir el que realmente encaja con tu función
Una guía práctica sobre las restricciones de tipos de servicio en primer plano de Android — dataSync, mediaPlayback, specialUse, shortService — y cómo elegir el correcto sin que te lo maten o te lo rechacen.