En este documento, se propone una nueva biblioteca de Jetpack para ayudar a los desarrolladores con la migración al entorno de ejecución de SDK. Explica cómo se admitirá el entorno de ejecución de SDK para versiones anteriores de la plataforma de Android (desde la compilación hasta la ejecución) y qué diferencias o limitaciones del entorno de ejecución pueden esperar los desarrolladores. Esta biblioteca permite a los desarrolladores crear una versión única de su app o SDK que incluya la capacidad de ejecutarse en dispositivos con o sin compatibilidad con el entorno de ejecución de SDK.
La retrocompatibilidad se logra a través de los siguientes componentes:
El complemento de Android para Gradle (AGP) + Bundletool compila una variante de app para dispositivos que no son compatibles con el entorno de ejecución de SDK empaquetando el entorno de ejecución de SDK en el APK.
La biblioteca cliente del entorno de ejecución de SDK (
androidx.privacysandbox.sdkruntime:sdkruntime-client
) carga el SDK en paquete desde los recursos de la app y emula el entorno de ejecución de SDK en dispositivos que no son compatibles con el entorno de ejecución de SDK.La biblioteca del proveedor del entorno de ejecución de SDK (
androidx.privacysandbox.sdkruntime:sdkruntime-provider
) proporciona una API para que los SDKs permitan la carga desde la biblioteca cliente del entorno de ejecución de SDK.
Publicación del SDK con Bundletool
En los dispositivos compatibles con el entorno de ejecución de SDK, los SDKs se entregarán y se instalarán como paquetes separados.
Para admitir versiones de plataforma que no son compatibles con el entorno de ejecución de SDK, Bundletool compilará una o más variantes del conjunto de APK de la app que incluyan todos los SDK de los que depende la app. Cada SDK se empaqueta como una división del APK independiente. Además, se realizan las siguientes transformaciones:
- Copia los archivos del código de bytes del SDK (DEX) en el SDK divididos como elementos.
- Copia los recursos de Java del SDK en el SDK divididos como elementos.
- Reasigna los recursos del SDK y combínalos con los recursos de la app.
- Genera archivos de configuración para la biblioteca cliente del entorno de ejecución de SDK.
Carga los SDKs con la biblioteca cliente del entorno de ejecución de SDK
La biblioteca cliente del entorno de ejecución de SDK proporciona APIs que son similares a las APIs de la plataforma, pero admiten los SDKs en el entorno del entorno de ejecución de SDK y los SDKs agrupados con la app de la variante.
Para usar la biblioteca cliente del entorno de ejecución de SDK, agrega la dependencia androidx.privacysandbox.sdkruntime:sdkruntime-client
y usa SdkSandboxManagerCompat
en lugar de SdkSandboxManager
.
Cuando una app intenta cargar un SDK, la biblioteca primero comprueba si el SDK se empaqueta con la app durante la compilación. Si se empaqueta, la biblioteca extrae el SDK de la división del SDK y lo carga en el proceso de la app. Si el SDK no se empaqueta con la app, la biblioteca delega la API de la plataforma para cargar el SDK.
Extrae un SDK de los recursos
Cuando una app intenta cargar un SDK empaquetado, la biblioteca cliente del entorno de ejecución de SDK verifica si los archivos DEX del SDK ya se extrajeron al almacenamiento del dispositivo (code_cache
) y, si no, los extrae de los recursos.
En general, la biblioteca extraerá archivos solo una vez después de instalar o actualizar una app.
Si el espacio de almacenamiento disponible es inferior al umbral permitido (actualmente, 100 MB) y no se extraen archivos DEX, la biblioteca intentará cargar el SDK directamente desde los elementos en dispositivos compatibles (nivel de API 27 o superior), lo que genera un uso de memoria más grande.
Cargador de clases para clases de SDK
Para evitar conflictos entre los SDKs y las clases de la app, todas las clases de SDK se cargan con un cargador de clases independiente y completamente independiente del cargador de clases principal de la app.
En el diseño actual del entorno de ejecución de SDK, todas las comunicaciones entre una app y los SDKs se realizan mediante llamadas IPC de Binder. Los mismos objetos de Binder del SDK se usan para los SDKs agrupados, y la serialización de transacciones de Binder permite a los desarrolladores de apps transmitir objetos de Binder de SDK a interfaces de Binder de SDK en el lado de la app.
Para otras interacciones internas (como inicializar un SDK, proporcionar una API de controlador a un SDK, etc.), la biblioteca usa Proxies dinámicos y la reflexión para funcionar en diferentes cargadores de clases.
Entorno del SDK
La biblioteca del proveedor de SDKRuntime proporciona APIs a los desarrolladores de SDK. Estas APIs son similares a las APIs de la plataforma, pero permiten que el entorno de ejecución de SDK y la biblioteca cliente de SDKRuntime carguen los SDKs.
Para poder usar el SDK de la biblioteca, debes agregar la dependencia androidx.privacysandbox.sdkruntime:sdkruntime-provider
y extender SandboxedSdkProviderCompat
en lugar de SandboxedSdkProvider
.
También debes usar SandboxedSdkProviderAdapter
como el proveedor del SDK para
permitir que el proveedor de compatibilidad se cargue en el entorno de ejecución del SDK.
SdkSandboxControllerCompat
delega a la API de la plataforma cuando el SDK se carga en el entorno de ejecución de SDK o delega a la biblioteca cliente de SDKRuntime cuando el SDK se carga como un SDK empaquetado.
En el caso de los SDKs agrupados, la biblioteca modifica el entorno del SDK de formas que emulan un comportamiento similar al del entorno de ejecución de SDK.
En las siguientes secciones, se describen los comportamientos esperados cuando la biblioteca cliente de SDKRuntime carga el SDK.
Recursos del SDK
Los recursos del SDK (res/) se admiten cuando el SDK se carga en el proceso de la app. Bundletool combina todos los recursos de los SDK con los recursos de la app.
Para evitar conflictos, se reasignan los recursos del SDK cambiando el prefijo packageId
en todos los IDs de recursos.
Cuando la biblioteca cliente de SDKRuntime carga el SDK, se actualiza packageId
en el entorno de ejecución para permitir la asignación de recursos reasignados mediante la clase R.
Recursos de Java
Los recursos Java son compatibles cuando el SDK se carga en el proceso de la app. Bundletool copia todos los recursos del SDK de Java en un directorio especial, en los recursos de app. La biblioteca cliente SDKRuntime usa un cargador de clases intermedio para redireccionar todas las llamadas relacionadas con los recursos de Java al nuevo directorio raíz.
Elementos del SDK
Los elementos del SDK se combinan con los recursos de aplicación sin reasignarlos.
Almacenamiento del SDK
Para admitir el almacenamiento de SDK, la biblioteca cliente del entorno de ejecución de SDK crea un directorio raíz dedicado para cada SDK agrupado en el almacenamiento de la app y proporciona un contexto especial que usa este directorio como raíz de almacenamiento.
Este contexto se puede recuperar desde SandboxedSdkProviderCompat#getContext
.
Métodos compatibles relacionados con el almacenamiento:
getDataDir
getCacheDir
getCodeCacheDir
getNoBackupFilesDir
getDir
getFilesDir
openFileInput
openFileOutput
deleteFile
getFileStreamPath
fileList
getDatabasePath
openOrCreateDatabase
moveDatabaseFrom
: Solo entre contextos de SDKdeleteDatabase
databaseList
getSharedPreferences
moveSharedPreferencesFrom
: Solo entre contextos de SDKdeleteSharedPreferences
Se puede crear un contexto de almacenamiento protegido por el dispositivo llamando a createDeviceProtectedStorageContext()
en ese contexto.
SdkSandboxControllerCompat
La biblioteca cliente de SDKRuntime proporciona la implementación de SdkSandboxControllerCompat
para los SDK agrupados que se cargan en el proceso de la app.
Si la biblioteca cliente no admite las APIs (por ejemplo, con un SDK compilado con una versión de la biblioteca más reciente que la versión de la app), se usará el resguardo más adecuado (no-ops o excepción).
Control de versiones
Cuando la biblioteca cliente de SDKRuntime carga un SDK empaquetado, realiza un protocolo de enlace con la biblioteca del proveedor de SDKRuntime dentro del SDK. Durante el protocolo de enlace, las bibliotecas intercambian sus versiones y ajustan el comportamiento para sustituir las APIs no disponibles por el resguardo más adecuado (no-ops o excepción).
Se recomienda usar la versión más reciente de la biblioteca tanto para los desarrolladores de apps como para los de SDK. De lo contrario, es posible que la funcionalidad que requiera compatibilidad en ambas partes no esté disponible.
Cualquier versión de la biblioteca cliente de SDKRuntime puede cargar un SDK con cualquier versión de la biblioteca del proveedor de SDKRuntime y viceversa.
En el futuro, se cambiará a la versión mínima de la biblioteca cliente necesaria para cargar el SDK con una versión específica de la biblioteca del proveedor.
Esto minimizará la fragmentación y ayudará a garantizar que la mayoría de las APIs sean compatibles si el SDK en paquete se cargó correctamente.
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Entorno de ejecución de SDK
- Guía para desarrolladores del entorno de ejecución del SDK
- Referencia de sdkruntime