En Android 8.0, el SO Android se rediseñó para definir interfaces claras.
entre la plataforma de Android independiente del dispositivo y ofertas específicas de dispositivos y proveedores
código. Android ya definió muchas de esas interfaces en forma de HAL.
definidas como encabezados de C en hardware/libhardware
. HIDL
reemplazaron estas interfaces de HAL por interfaces estables con control de versiones, que pueden
estar en Java (como se describe a continuación) o ser HIDL del cliente y del servidor
interfaces en C++.
Las interfaces HIDL están diseñadas para usarse principalmente a partir de código nativo y como HIDL de resultado se enfoca en la generación automática de código eficiente en C++. Sin embargo, Las interfaces HIDL también deben estar disponibles para usarse directamente desde Java, ya que algunos dispositivos subsistemas (como Telefonía) tienen interfaces HIDL de Java.
En las páginas de esta sección, se describe el frontend de Java para las interfaces HIDL, se detalla cómo crear, registrar y usar servicios, y se explica cómo las HAL y las HAL los clientes escritos en Java interactúan con el sistema de RPC HIDL.
Ejemplo de cliente
Este es un ejemplo de un cliente para una interfaz IFoo
en el paquete
android.hardware.foo@1.0
registrado como nombre de servicio
default
y un servicio adicional con el nombre del servicio personalizado
second_impl
Cómo agregar bibliotecas
Debes agregar dependencias en la biblioteca de stub HIDL correspondiente si quieres usarlo. Por lo general, es una biblioteca estática:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Si sabes que ya estás extrayendo dependencias en estas bibliotecas, también pueden usar la vinculación compartida:
// in Android.bp libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Consideraciones adicionales para agregar bibliotecas en Android 10
Si tienes una app del sistema o de un proveedor orientada a Android 10 o versiones posteriores, haz lo siguiente:
puedes incluirlas de forma estática. También puedes usar (solo) clases HIDL
a partir de archivos JAR personalizados instalados en el dispositivo con APIs de Java estables disponibles
con el mecanismo uses-library
existente para apps del sistema El
este último enfoque ahorra espacio en el dispositivo. Para obtener más detalles, consulta Cómo implementar la biblioteca del SDK de Java. Para
en las apps más antiguas, se conserva el comportamiento anterior.
A partir de Android 10, la versión "superficial" de estas bibliotecas
también están disponibles. Incluyen la clase en cuestión, pero no incluyen
de las clases dependientes. Por ejemplo:
android.hardware.foo-V1.0-java-shallow
incluye clases en el archivo foo.
paquete, pero no incluye clases en
android.hidl.base-V1.0-java
, que contiene la clase base de todas
Interfaces de HIDL Si estás creando una biblioteca que ya tiene la biblioteca
disponibles como dependencia, puedes usar lo siguiente:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java-shallow", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java-shallow
Las bibliotecas de administrador y base de HIDL tampoco están disponibles en el arranque
de clase para las apps (antes, a veces se usaban como API oculta, debido a
cargador de clases primero delegado de Android). sino que se trasladaron a un nuevo
espacio de nombres con jarjar
y las apps que las usan (necesariamente, priv
apps) deben tener sus propias copias independientes. módulos en la ruta de clase de inicio con
HIDL debe usar las variantes superficiales de estas bibliotecas Java y agregar
jarjar_rules: ":framework-jarjar-rules"
a su
Android.bp
para usar la versión existente de estas bibliotecas
en la ruta de clase de inicio.
Modifica tu código fuente de Java
Solo hay una versión (@1.0
) de este servicio, por lo que este código
recupera solo esa versión. Consulta
extensiones de interfaz
sobre cómo manejar varias versiones diferentes del servicio.
import android.hardware.foo.V1_0.IFoo; ... // retry to wait until the service starts up if it is in the manifest IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available IFoo anotherServer = IFoo.getService("second_impl", true /* retry */); server.doSomething(…);
Proporcionar un servicio
Es posible que el código del framework en Java deba entregar interfaces para recibir de las HALs.
En el caso de la interfaz IFooCallback
de la versión 1.0 de la
android.hardware.foo
, puedes implementar la interfaz en
Java con los siguientes pasos:
- Define tu interfaz en HIDL.
- Abrir
/tmp/android/hardware/foo/IFooCallback.java
como referencia. - Crea un módulo nuevo para tu implementación de Java.
- Examina la clase abstracta
android.hardware.foo.V1_0.IFooCallback.Stub
y, luego, escribe una clase nueva para extenderlo e implementar los métodos abstractos.
Cómo ver archivos generados automáticamente
Para ver los archivos generados automáticamente, ejecuta lo siguiente:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
Estos comandos generan el directorio
/tmp/android/hardware/foo/1.0
Para el archivo
hardware/interfaces/foo/1.0/IFooCallback.hal
, genera la
archivo /tmp/android/hardware/foo/1.0/IFooCallback.java
, que
encapsula la interfaz de Java, el código del proxy y los stubs (proxy y
los stubs cumplen con la interfaz).
-Lmakefile
genera las reglas que ejecutan este comando en la compilación.
tiempo y te permitirá incluir
android.hardware.foo-V1.0-java
y vincúlalo con el
los archivos correspondientes. Una secuencia de comandos que hace esto
automáticamente para un proyecto lleno
estas interfaces en hardware/interfaces/update-makefiles.sh
.
En este ejemplo, las rutas de acceso son relativas; las interfaces o el hardware pueden ser
bajo tu árbol de código para poder desarrollar una HAL antes de
publicarlo.
Ejecuta un servicio
La HAL proporciona la interfaz IFoo
, que debe hacer que la arquitectura
devoluciones de llamadas al framework a través de la interfaz IFooCallback
. El
La interfaz IFooCallback
no está registrada por nombre como detectable
servicio; en su lugar, IFoo
debe contener un método como
setFooCallback(IFooCallback x)
Para configurar IFooCallback
desde la versión 1.0 de la
Paquete android.hardware.foo
, agregar
android.hardware.foo-V1.0-java
a Android.mk
. El código
para ejecutar el servicio es:
import android.hardware.foo.V1_0.IFoo; import android.hardware.foo.V1_0.IFooCallback.Stub; .... class FooCallback extends IFooCallback.Stub { // implement methods } .... // Get the service from which you will be receiving callbacks. // This also starts the threadpool for your callback service. IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available .... // This must be a persistent instance variable, not local, // to avoid premature garbage collection. FooCallback mFooCallback = new FooCallback(); .... // Do this once to create the callback service and tell the "foo-bar" service server.setFooCallback(mFooCallback);
Extensiones de interfaz
Si suponemos que un servicio determinado implementa la interfaz IFoo
en todos
es posible que, en un dispositivo en particular, el servicio proporcione
capacidades adicionales implementadas en la extensión de la interfaz
IBetterFoo
de la siguiente manera:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Llamar a un reconocimiento de código de la interfaz extendida puede usar el
castFrom()
para convertir de manera segura la interfaz base al
Interfaz extendida:
IFoo baseService = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available IBetterFoo extendedService = IBetterFoo.castFrom(baseService); if (extendedService != null) { // The service implements the extended interface. } else { // The service implements only the base interface. }