Métodos de interfaz y Errores

Esta sección detalla los métodos y errores de la interfaz.

métodos nulos

Los métodos que no devuelven resultados se traducen a métodos Java que devuelven void . Por ejemplo, la declaración HIDL:

doThisWith(float param);

… se convierte en:

void doThisWith(float param);

Métodos de resultado único

Los métodos que devuelven un único resultado se traducen a sus equivalentes de Java y también devuelven un único 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 resultados múltiples

Para cada método que devuelve 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 del 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);

Una persona que llama a oneProducesTwoThings() normalmente usaría una clase interna anónima o lambda para implementar la devolución de llamada localmente:

someInstanceOfFoo.oneProducesTwoThings(
         5 /* x */,
         new IFoo.oneProducesTwoThingsCallback() {
          @Override
          void onValues(double a, double b) {
             // do something interesting with a and b.
             ...
          }});

o:

someInstanceOfFoo.oneProducesTwoThings(5 /* x */,
    (a, b) -> a > 3.0 ? f(a, b) : g(a, b)));

También puedes definir una clase para usar como devolución de llamada...

class MyCallback implements oneProducesTwoThingsCallback {
  public void onValues(double a, double b) {
    // do something interesting with a and b.
  }
}

… y pasar una instancia de MyCallback como tercer parámetro a oneProducesTwoThings() .

Errores de transporte y muerte de destinatarios

Debido a que las implementaciones de servicios pueden ejecutarse en un proceso diferente, en algunos casos el cliente puede permanecer vivo incluso cuando el proceso que implementa una interfaz muere. Las llamadas a un objeto de interfaz alojado en un proceso inactivo fallan con un error de transporte (una excepción de tiempo de ejecución lanzada por el método llamado). La recuperación de tal falla es posible solicitando una nueva instancia del servicio llamando I<InterfaceName>.getService() . Sin embargo, este método solo funciona si el proceso que falló se reinició y volvió a registrar sus servicios con el administrador de servicios (lo que generalmente es cierto para las implementaciones HAL).

Los clientes de una interfaz también pueden registrar un destinatario fallido para recibir una notificación cuando un servicio falle. Aún pueden ocurrir errores de transporte si se realiza una llamada justo cuando el servidor muere. Para registrarse para recibir dichas 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 proporcionada por HIDL. La interfaz contiene un método único serviceDied() que se llama cuando el proceso que aloja la interfaz muere.

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 destinatario de fallecimiento después de registrarlo usando:

foo.unlinkToDeath(recipient);