Android 10 incluye cambios actualizados en el comportamiento del sistema que podrían afectar tu app.
Los cambios que se indican en esta página se aplican exclusivamente a las apps orientadas a la
API 29 o versiones posteriores. Si tu app establece targetSdkVersion en "29" o un valor superior, debes modificarla para que admita estos comportamientos correctamente, cuando corresponda.
Asegúrate de revisar también la lista de cambios en el comportamiento que afectan a todas las apps que se ejecutan en Android 10.
Nota: Además de los cambios que se indican en esta página, Android 10 presenta una gran cantidad de cambios y restricciones basados en la privacidad, incluidos los siguientes:
- Almacenamiento específico
- Acceso al número de serie del dispositivo USB
- Capacidad para habilitar, inhabilitar y configurar el Wi-Fi
- Permisos de ubicación para las APIs de conectividad
Estos cambios, que afectan a las apps orientadas al nivel de API 29 o versiones posteriores, mejoran la privacidad del usuario. Para obtener más información sobre cómo admitir estos cambios, consulta la página Cambios en la privacidad.
Actualizaciones a restricciones de interfaces no SDK
Para garantizar la estabilidad y compatibilidad de las apps, la plataforma comenzó a restringir las interfaces que no pertenecen al SDK que tu app puede usar en Android 9 (nivel de API 28). Android 10 incluye listas actualizadas de interfaces restringidas que no pertenecen al SDK, basadas en la colaboración con desarrolladores de Android y las pruebas internas más recientes. Nuestro objetivo es asegurarnos de que las alternativas públicas estén disponibles antes de restringir las interfaces que no pertenecen al SDK.
Si no orientas tu app a Android 10 (nivel de API 29), es posible que algunos de estos cambios no te afecten de inmediato. Sin embargo, aunque actualmente puedes usar algunas interfaces que no pertenecen al SDK (según el nivel de API al que esté orientada la app), utilizar cualquier método o campo que no pertenezca al SDK siempre implica un gran riesgo de error para tu app.
En caso de no saber con certeza si tu app usa este tipo de interfaces, puedes probarla para verificarlo. Si tu app depende de interfaces que no pertenezcan al SDK, deberías planificar una migración hacia otras alternativas que sí lo hagan. Sin embargo, sabemos que algunas apps tienen casos prácticos válidos para usarlas. Si no encuentras una alternativa al uso de una interfaz que no pertenece al SDK para una función de tu app, deberías solicitar una nueva API pública.
Para obtener más información, consulta Actualizaciones de las restricciones de interfaces que no pertenecen al SDK en Android 10 y Restricciones en interfaces que no pertenecen al SDK.
Memoria compartida
Ashmem cambió el formato de los mapas de Dalvik en /proc/<pid>/maps, lo que afecta a las apps que analizan directamente el archivo de mapas. Los desarrolladores de aplicaciones deben probar el formato /proc/<pid>/maps en dispositivos que ejecutan Android 10 o versiones posteriores, y analizarlo según corresponda si la app depende de los formatos de mapas de Dalvik.
Las apps orientadas a Android 10 no pueden usar ashmem (/dev/ashmem) directamente y, en su lugar, deben acceder a la memoria compartida a través de la clase ASharedMemory del NDK.
Además, las apps no pueden realizar IOCTL directas a los descriptores de archivos de ashmem existentes y, en su lugar, deben usar la clase ASharedMemory del NDK o las APIs de Java de Android para crear regiones de memoria compartida. Este cambio aumenta la seguridad y
la solidez cuando se trabaja con memoria compartida, lo que mejora el rendimiento y la seguridad
de Android en general.
Se quitó el permiso de ejecución para el directorio principal de la app
La ejecución de archivos desde el directorio principal de la app que admite escritura es una infracción de W^X. Las apps solo deben cargar el código binario incorporado en el archivo APK de una app.
Las apps no confiables que se orientan a Android 10 no pueden invocar a execve() directamente en archivos dentro del directorio principal de la app.
Además, las apps que se orientan a Android 10 no pueden modificar en la memoria el código ejecutable de los archivos que se abrieron con dlopen() y esperar que esos cambios se escriban en el disco, ya que la biblioteca no se puede asignar como PROT_EXEC a través de un descriptor de archivo que se pueda escribir. Esto incluye cualquier archivo de objeto (.so) compartido con reubicaciones de texto.
El tiempo de ejecución de Android solo acepta archivos OAT generados por el sistema
El entorno de ejecución de Android (ART) ya no invoca dex2oat desde el proceso de la aplicación. Este cambio significa que ART solo aceptará archivos OAT que haya generado el sistema.
Implementación de corrección AOT en ART
En el pasado, la compilación anticipada (AOT) que realizaba Android Runtime (ART) podía causar fallas en el tiempo de ejecución si el entorno de la ruta de clase no era el mismo en el tiempo de compilación y en el tiempo de ejecución. Android 10 y versiones posteriores siempre requieren que estos contextos de entorno sean los mismos, lo que genera los siguientes cambios en el comportamiento:
- Los cargadores de clases personalizados, es decir, los cargadores de clases escritos por apps, a diferencia de los cargadores de clases del paquete
dalvik.system, no se compilan con AOT. Esto se debe a que ART no puede conocer la implementación personalizada de búsqueda de clases en el entorno de ejecución. - Los archivos DEX secundarios, es decir, los archivos DEX que las apps cargan de forma manual y que no están en el APK principal, se compilan con AOT en segundo plano. Esto se debe a que la compilación de primer uso puede ser demasiado costosa, lo que genera una latencia no deseada antes de la ejecución. Ten en cuenta que, para las apps, se recomienda adoptar divisiones y dejar de usar archivos DEX secundarios.
- Las bibliotecas compartidas en Android (las entradas <library> y <uses-library> en un manifiesto de Android) se implementan con una jerarquía de cargador de clases diferente de la que se usa en las versiones anteriores de la plataforma.
Cambios en los permisos para intents de pantalla completa
Las apps que se orientan a Android 10 o versiones posteriores y usan notificaciones con intents de pantalla completa deben solicitar el permiso USE_FULL_SCREEN_INTENT en el archivo de manifiesto de la app. Este es un permiso normal, por lo que el sistema lo otorga automáticamente a la app que lo solicita.
Si una app orientada a Android 10 o versiones posteriores intenta crear una notificación con un intent de pantalla completa sin solicitar el permiso necesario, el sistema ignora el intent de pantalla completa y genera el siguiente mensaje de registro:
Package your-package-name: Use of fullScreenIntent requires the USE_FULL_SCREEN_INTENT permission
Compatibilidad con dispositivos plegables
Android 10 tiene cambios compatibles con dispositivos de pantalla grande y plegables.
Cuando una app se ejecuta en Android 10, los métodos onResume() y onPause() funcionan de manera diferente. Cuando aparecen varias apps al mismo tiempo en el modo multiventana o
multipantalla, todas las actividades principales enfocables de las pilas visibles
están en estado reanudado, pero solo una de ellas, la actividad "reanudada principal",
tiene el enfoque. Cuando se ejecuta en versiones anteriores a Android 10, solo se puede reanudar una actividad en el sistema a la vez, y todas las demás actividades visibles se pausan.
No confundas el "foco" con la actividad "más reanudada". El sistema asigna prioridades a las actividades según el orden Z para dar mayor prioridad a las actividades con las que el usuario interactuó por última vez. Una actividad puede estar en el estado de reanudación superior, pero no estar enfocada (por ejemplo, si el panel de notificaciones está expandido).
En Android 10 (nivel de API 29) y versiones posteriores, puedes suscribirte a la devolución de llamada onTopResumedActivityChanged() para recibir una notificación cuando tu actividad adquiera o pierda la posición reanudada superior. Esto equivale al estado reanudado antes de Android 10 y puede ser útil como sugerencia si tu app usa recursos exclusivos o de singleton que podrían necesitar compartirse con otras apps.
También cambió el comportamiento del atributo de manifiesto resizeableActivity. Si una app establece resizeableActivity=false en Android 10 (nivel de API 29) o versiones posteriores, es posible que se coloque en modo de compatibilidad cuando cambie el tamaño de la pantalla disponible o si la app se mueve de una pantalla a otra.
Las apps pueden usar el atributo android:minAspectRatio, que se introdujo en Android 10, para indicar las proporciones de pantalla que admite tu app.
A partir de la versión 3.5, la herramienta de emulador de Android Studio incluye dispositivos virtuales de 7.3" y 8" para probar tu código con pantallas más grandes.
Para obtener más información, consulta Cómo diseñar tus apps para dispositivos plegables.