Schnittstellenmethoden & Fehler

In diesem Abschnitt werden Schnittstellenmethoden und -fehler beschrieben.

Void-Methoden

Methoden, die keine Ergebnisse zurückgeben, werden in Java-Methoden übersetzt, die void zurückgeben. Zum Beispiel die HIDL-Deklaration:

doThisWith(float param);

… wird:

void doThisWith(float param);

Einzelergebnismethoden

Methoden, die ein einzelnes Ergebnis zurückgeben, werden in ihre Java-Äquivalente übersetzt, die ebenfalls ein einzelnes Ergebnis zurückgeben. Zum Beispiel Folgendes:

doQuiteABit(int32_t a, int64_t b,
            float c, double d) generates (double something);

… wird:

double doQuiteABit(int a, long b, float c, double d);

Methoden mit mehreren Ergebnissen

Für jede Methode, die mehr als ein Ergebnis zurückgibt, wird eine Callback-Klasse generiert, die alle Ergebnisse in ihrer onValues Methode bereitstellt. Dieser Rückruf fungiert als zusätzlicher Parameter für die Methode. Zum Beispiel Folgendes:

oneProducesTwoThings(SomeEnum x) generates (double a, double b);

… wird:

public interface oneProducesTwoThingsCallback {
    public void onValues(double a, double b);
}
void oneProducesTwoThings(byte x, oneProducesTwoThingsCallback cb);

Ein Aufrufer von oneProducesTwoThings() würde normalerweise eine anonyme innere Klasse oder ein Lambda verwenden, um den Rückruf lokal zu implementieren:

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

oder:

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

Sie können auch eine Klasse definieren, die als Rückruf verwendet wird …

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

… und übergeben Sie eine Instanz von MyCallback als dritten Parameter an oneProducesTwoThings() .

Transportfehler und Sterbeempfänger

Da Dienstimplementierungen in einem anderen Prozess ausgeführt werden können, kann der Client in manchen Fällen auch dann am Leben bleiben, wenn der Prozess, der eine Schnittstelle implementiert, ausfällt. Aufrufe eines Schnittstellenobjekts, das in einem toten Prozess gehostet wird, schlagen mit einem Transportfehler (einer von der aufgerufenen Methode ausgelösten Laufzeitausnahme) fehl. Eine Wiederherstellung nach einem solchen Fehler ist möglich, indem eine neue Instanz des Dienstes durch Aufruf I<InterfaceName>.getService() angefordert wird. Diese Methode funktioniert jedoch nur, wenn der abgestürzte Prozess neu gestartet und seine Dienste erneut beim Servicemanager registriert hat (was im Allgemeinen für HAL-Implementierungen gilt).

Clients einer Schnittstelle können auch einen Todesempfänger registrieren, um eine Benachrichtigung zu erhalten, wenn ein Dienst ausfällt. Transportfehler können immer noch auftreten, wenn ein Anruf gerade dann erfolgt, wenn der Server ausfällt. Um sich für solche Benachrichtigungen auf einer abgerufenen IFoo Schnittstelle zu registrieren, kann ein Client Folgendes tun:

foo.linkToDeath(recipient, 1481 /* cookie */);

Der recipient muss eine Implementierung der von HIDL bereitgestellten Schnittstelle HwBinder.DeathRecipient sein. Die Schnittstelle enthält eine einzelne Methode serviceDied() , die aufgerufen wird, wenn der Prozess, der die Schnittstelle hostet, stirbt.

final class DeathRecipient implements HwBinder.DeathRecipient {
    @Override
    public void serviceDied(long cookie) {
        // Deal with service going away
    }
}

Der cookie Parameter enthält das Cookie, das mit dem Aufruf von linkToDeath() übergeben wurde. Es ist auch möglich, einen Sterbeempfänger nach der Registrierung abzumelden, indem Sie Folgendes tun:

foo.unlinkToDeath(recipient);