En esta sección, se detallan los métodos y errores de la interfaz.
Métodos nulos
Los métodos que no muestran resultados se traducen a métodos de Java que muestran void
. Por ejemplo, la declaración de HIDL:
doThisWith(float param);
… se convierte en:
void doThisWith(float param);
Métodos de un solo resultado
Los métodos que muestran un solo resultado se traducen a sus equivalentes de Java, que también muestran un solo resultado. Por ejemplo, lo siguiente:
doQuiteABit(int32_t a, int64_t b, float c, double d) generates (double something);
… se convierte en:
double doQuiteABit(int a, long b, float c, double d);
Métodos de varios resultados
Para cada método que muestra más de un resultado, se genera una clase de devolución de llamada que proporciona todos los resultados en su método onValues
.
Esa devolución de llamada actúa como un parámetro adicional para el método. Por ejemplo, lo siguiente:
oneProducesTwoThings(SomeEnum x) generates (double a, double b);
… se convierte en:
public interface oneProducesTwoThingsCallback { public void onValues(double a, double b); } void oneProducesTwoThings(byte x, oneProducesTwoThingsCallback cb);
Por lo general, un llamador de oneProducesTwoThings()
usaría una clase interna o lambda anónima para implementar la devolución de llamada de forma local:
someInstanceOfFoo.oneProducesTwoThings( 5 /* x */, new IFoo.oneProducesTwoThingsCallback() { @Override void onValues(double a, double b) { // do something interesting with a and b. ... }});
O bien:
someInstanceOfFoo.oneProducesTwoThings(5 /* x */, (a, b) -> a > 3.0 ? f(a, b) : g(a, b)));
También puedes definir una clase para usarla como devolución de llamada …
class MyCallback implements oneProducesTwoThingsCallback { public void onValues(double a, double b) { // do something interesting with a and b. } }
… y pasa una instancia de MyCallback
como tercer parámetro a oneProducesTwoThings()
.
Errores de transporte y destinatarios fallecidos
Debido a que las implementaciones de servicios pueden ejecutarse en un proceso diferente, en algunos casos, el cliente puede permanecer activo incluso cuando se cierra el proceso que implementa una interfaz.
Las llamadas a un objeto de interfaz alojado en un proceso cerrado fallan con un error de transporte (una excepción de tiempo de ejecución que arroja el método llamado). Para recuperarse de una falla de este tipo, llama a I<InterfaceName>.getService()
para solicitar una instancia nueva del servicio. Sin embargo, este método solo funciona si el proceso que falló se reinició y volvió a registrar sus servicios con el servicemanager (lo que suele ser cierto para las implementaciones de HAL).
Los clientes de una interfaz también pueden registrar un destinatario de error para recibir una notificación cuando un servicio falle. Aún pueden ocurrir errores de transporte si se realiza una llamada justo cuando se cierra el servidor. Para registrarse para recibir esas notificaciones en una interfaz IFoo
recuperada, un cliente puede hacer lo siguiente:
foo.linkToDeath(recipient, 1481 /* cookie */);
El parámetro recipient
debe ser una implementación de la interfaz HwBinder.DeathRecipient
que proporciona HIDL. La interfaz contiene un solo método serviceDied()
al que se llama cuando finaliza el proceso que aloja la interfaz.
final class DeathRecipient implements HwBinder.DeathRecipient { @Override public void serviceDied(long cookie) { // Deal with service going away } }
El parámetro cookie
contiene la cookie que se pasó con la llamada a linkToDeath()
. También es posible cancelar el registro de un beneficiario de defunción después de registrarlo con lo siguiente:
foo.unlinkToDeath(recipient);