La plataforma de Android contiene una gran cantidad de bibliotecas de Java compartidas que pueden incluirse opcionalmente en la ruta de clase de las apps con la etiqueta <uses-library>
en el manifiesto de la app. Las apps se vinculan con estas bibliotecas, por lo que debes tratarlas como al resto de las APIs de Android en términos de compatibilidad, revisión de la API y compatibilidad con herramientas. Sin embargo, ten en cuenta que la mayoría de las bibliotecas no tienen estas funciones.
El tipo de módulo java_sdk_library
ayuda con la administración de bibliotecas de esta clase. Los fabricantes de dispositivos pueden usar este mecanismo en sus propias bibliotecas de Java compartidas para mantener la retrocompatibilidad con las APIs.
Si los fabricantes de dispositivos usan sus propias bibliotecas de Java compartidas a través de la etiqueta <uses-library>
en lugar de la ruta de inicio de la clase, java_sdk_library
puede verificar que esas bibliotecas de Java sean estables para la API.
java_sdk_library
implementa APIs del SDK opcionales para uso de las apps. Las bibliotecas implementadas con java_sdk_library
en tu archivo de compilación (Android.bp
) llevan a cabo las siguientes operaciones:
- Se generan bibliotecas de stubs para incluir
stubs
,stubs.system
ystubs.test
. Esto se hace a través del reconocimiento de las anotaciones@hide
,@SystemApi
y@TestApi
. java_sdk_library
administra los archivos de especificación de API (comocurrent.txt
) en un subdirectorio de la API. Estos archivos se comparan con el código más reciente para garantizar que sean las versiones más actualizadas. Si no lo son, recibirás un mensaje de error que explica cómo actualizarlos. Revisa de forma manual todos los cambios de la actualización para asegurarte de que cumplan con tus expectativas.
Para actualizar todas las APIs, usam update-api
. Si deseas verificar que una API esté actualizada, usam checkapi
.- Los archivos de especificación de la API se comparan con las versiones más recientes de Android que se hayan publicado para garantizar que la API sea retrocompatible con las versiones anteriores. Los módulos
java_sdk_library
proporcionados como parte de AOSP ubican sus versiones anteriores enprebuilts/sdk/<latest number>
. - Con respecto a las verificaciones de archivos de especificación de la API, puedes realizar una de las siguientes tres acciones:
- Permitir que se hagan las verificaciones para continuar (sin acciones)
- Agregar lo siguiente a
java_sdk_library
para inhabilitar las verificaciones:
unsafe_ignore_missing_latest_api: true,
- Crear archivos de texto vacíos llamados
module_name.txt
en el directorioversion/scope/api
y proporcionar APIs vacías para nuevos módulosjava_sdk_library
- Si se instaló la biblioteca de implementación para el tiempo de ejecución, se generará e instalará un archivo XML.
Cómo funciona java_sdk_library
Un elemento java_sdk_library
llamado X
crea lo siguiente:
- Dos copias de la biblioteca de implementación: una que se llama
X
y otra que se llamaX.impl
. La bibliotecaX
está instalada en el dispositivo. La bibliotecaX.impl
, en cambio, solo se instala si otros módulos necesitan acceso explícito a la biblioteca de implementación, por ejemplo, para usarla en pruebas. Ten en cuenta que rara vez se necesita un acceso explícito. - Se pueden habilitar o inhabilitar los alcances para personalizar el acceso (al igual que los modificadores de acceso de palabras clave de Java, un alcance público proporciona un amplio rango de acceso; un alcance de prueba contiene las APIs que solo se usan en pruebas). Para cada alcance habilitado, la biblioteca crea los siguientes elementos:
- Un módulo de origen de stub (de tipo de módulo
droidstubs
): Consume la fuente de implementación y da como resultado un conjunto de fuentes de stub junto con el archivo de especificación de la API. - Una biblioteca de stubs (de tipo de módulo
java_library
): Es la versión compilada de los stubs. Las bibliotecas que se usan para compilar esto no son las mismas que se proporcionan ajava_sdk_library
, lo que garantiza que los detalles de implementación no se filtren en los stubs de la API. - Si necesitas bibliotecas adicionales para compilar los stubs, usa las propiedades
stub_only_libs
ystub_only_static_libs
para proporcionarlas.
Si una java_sdk_library
se llama "X
" y se está compilando como "X
", siempre haz referencia a ella de esa manera y no la modifiques. La compilación seleccionará una biblioteca adecuada. Para asegurarte de tener la biblioteca más adecuada, inspecciona tus stubs y revisa si la compilación introdujo errores. Haz las correcciones necesarias con esta guía:
- Verifica que la biblioteca sea adecuada. Para ello, observa la línea de comandos y consulta qué stubs se enumeran allí para determinar el alcance:
- El alcance es demasiado amplio: La biblioteca dependiente necesita un cierto alcance de las APIs. Sin embargo, verás APIs incluidas en la biblioteca que quedan fuera de ese alcance, como las APIs del sistema incluidas con las APIs públicas.
- El alcance es demasiado limitado: La biblioteca dependiente no tiene acceso a todas las bibliotecas requeridas. Por ejemplo, la biblioteca dependiente necesita usar la API del sistema, pero recibe la API pública en su lugar. Por lo general, esto genera un error de compilación porque faltan las APIs necesarias.
- Para corregir la biblioteca, realiza solo una de las siguientes acciones:
- Cambia
sdk_version
para seleccionar la versión que necesitas. O BIEN - Especifica de forma explícita la biblioteca adecuada, como
<X>.stubs
o<X>.stubs.system
.
Uso de la java_sdk_library X
La biblioteca de implementación X
se usa cuando se hace referencia a ella desde apex.java_libs
. Sin embargo, debido a una limitación de Soong, si se hace referencia a la biblioteca X
desde otro módulo java_sdk_library
dentro de la misma biblioteca de APEX, se debe usar explícitamente X.impl
en lugar de la biblioteca X
.
Cuando se hace referencia a java_sdk_library
desde otro lugar, se usa una biblioteca de stubs. La biblioteca de stubs se selecciona según el parámetro de configuración de la propiedad sdk_version
del módulo dependiente. Por ejemplo, un módulo que especifica sdk_version: "current"
usa stubs públicos, mientras que un módulo que especifica sdk_version: "system_current"
usa stubs del sistema. Si no se encuentra una concordancia exacta, se usa la biblioteca de stubs más cercana. Una java_sdk_library
que solo proporciona una API pública proporcionará los stubs públicos para todos.
![Flujo de compilación con la biblioteca del SDK de Java](https://source.android.com/static/docs/core/architecture/images/build-flow-java-lib.png?authuser=1&hl=es-419)
Ejemplos y fuentes
Las propiedades srcs
y api_packages
deben estar presentes en la java_sdk_library
.
java_sdk_library { name: "com.android.future.usb.accessory", srcs: ["src/**/*.java"], api_packages: ["com.android.future.usb"], }
AOSP recomienda (pero no requiere) que las nuevas instancias de java_sdk_library
habiliten de forma explícita los alcances de la API que se quieran usar. También puedes migrar (de manera opcional) las instancias existentes de java_sdk_library
para habilitar explícitamente los alcances de la API que usarán:
java_sdk_library { name: "lib", public: { enabled: true, }, system: { enabled: true, }, … }
Para configurar la biblioteca impl
que se usará durante la ejecución, utiliza todas las propiedades normales de java_library
, como hostdex
, compile_dex
y errorprone
.
java_sdk_library { name: "android.test.base", srcs: ["src/**/*.java"], errorprone: { javacflags: ["-Xep:DepAnn:ERROR"], }, hostdex: true, api_packages: [ "android.test", "android.test.suitebuilder.annotation", "com.android.internal.util", "junit.framework", ], compile_dex: true, }
Para configurar bibliotecas de stubs, usa las siguientes propiedades:
merge_annotations_dirs
ymerge_inclusion_annotations_dirs
.api_srcs
: Es la lista de archivos de origen opcionales que forman parte de la API, pero no de la biblioteca del entorno de ejecución.stubs_only_libs
: Es la lista de bibliotecas de Java que se encuentran en la ruta de clase cuando se compilan stubs.hidden_api_packages
: Es la lista de nombres de paquetes que deben estar ocultos de la API.droiddoc_options
: Es un argumento adicional de metalava.droiddoc_option_files
: Enumera los archivos a los que se puede hacer referencia desdedroiddoc_options
con$(location <label>)
, en el que<file>
es una entrada en la lista.annotations_enabled
.
java_sdk_library
es una java_library
, pero no es un módulo droidstubs
y, por lo tanto, no es compatible con todas las propiedades de droidstubs
. El siguiente ejemplo se tomó del archivo de compilación de biblioteca android.test.mock.
java_sdk_library { name: "android.test.mock", srcs: [":android-test-mock-sources"], api_srcs: [ // Note: The following aren’t APIs of this library. Only APIs under the // android.test.mock package are taken. These do provide private APIs // to which android.test.mock APIs reference. These classes are present // in source code form to access necessary comments that disappear when // the classes are compiled into a Jar library. ":framework-core-sources-for-test-mock", ":framework_native_aidl", ], libs: [ "framework", "framework-annotations-lib", "app-compat-annotations", "Unsupportedappusage", ], api_packages: [ "android.test.mock", ], permitted_packages: [ "android.test.mock", ], compile_dex: true, default_to_stubs: true, }
Cómo mantener la retrocompatibilidad
El sistema de compilación verifica si las APIs mantuvieron la retrocompatibilidad comparando los archivos de la API más recientes con los que se generaron al momento de la compilación. java_sdk_library
verifica la compatibilidad con la información proporcionada por prebuilt_apis
.
Todas las bibliotecas compiladas con java_sdk_library
deben tener archivos de API en la versión más reciente de api_dirs
en prebuilt_apis
.
Cuando lanzas la versión, la API enumera los archivos, y se pueden obtener las bibliotecas de stubs con compilación dist con PRODUCT=sdk_phone_armv7-sdk
.
La propiedad api_dirs
es una lista de directorios de versiones de API en prebuilt_apis
. Los directorios de versiones de API deben estar ubicados en el nivel del directorio Android.bp
.
prebuilt_apis { name: "foo", api_dirs: [ "1", "2", .... "30", "current", ], }
Configura los directorios con la estructura version/scope/api/
en el directorio de compilaciones previas. version
corresponde al nivel de API y scope
define si el directorio es público, del sistema o de prueba.
version/scope
contiene bibliotecas Java.version/scope/api
contiene archivos.txt
de API. Crea archivos de texto vacíos llamadosmodule_name.txt
ymodule_name-removed.txt
aquí.├── 30 │ ├── public │ │ ├── api │ │ │ ├── android.test.mock-removed.txt │ │ │ └── android.test.mock.txt │ │ └── android.test.mock.jar │ ├── system │ │ ├── api │ │ │ ├── android.test.mock-removed.txt │ │ │ └── android.test.mock.txt │ │ └── android.test.mock.jar │ └── test │ ├── api │ │ ├── android.test.mock-removed.txt │ │ └── android.test.mock.txt │ └── android.test.mock.jar └── Android.bp