Métodos y errores de interfaz

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);