Metody interfejsu & Błędy

W tej sekcji szczegółowo opisano metody i błędy interfejsu.

Metody puste

Metody, które nie zwracają wyników, są tłumaczone na metody Java, które zwracają void . Na przykład deklaracja HIDL:

doThisWith(float param);

… staje się:

void doThisWith(float param);

Metody pojedynczego wyniku

Metody zwracające pojedynczy wynik są tłumaczone na ich odpowiedniki w języku Java, które również zwracają pojedynczy wynik. Na przykład:

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

… staje się:

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

Metody wielu wyników

Dla każdej metody zwracającej więcej niż jeden wynik generowana jest klasa wywołania zwrotnego, która dostarcza wszystkie wyniki metody onValues . To wywołanie zwrotne działa jako dodatkowy parametr metody. Na przykład:

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

… staje się:

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

Osoba wywołująca oneProducesTwoThings() zazwyczaj używa anonimowej klasy wewnętrznej lub lambdy do lokalnego wdrożenia wywołania zwrotnego:

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

Lub:

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

Możesz także zdefiniować klasę, która będzie używana jako wywołanie zwrotne…

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

… i przekaż instancję MyCallback jako trzeci parametr do oneProducesTwoThings() .

Błędy w transporcie i odbiorcy śmierci

Ponieważ implementacje usług mogą przebiegać w ramach innego procesu, w niektórych przypadkach klient może pozostać przy życiu nawet wtedy, gdy proces implementujący interfejs ulegnie awarii. Wywołania obiektu interfejsu hostowanego w martwym procesie kończą się niepowodzeniem z powodu błędu transportu (wyjątek czasu wykonania zgłoszony przez wywoływaną metodę). Odzyskiwanie po takiej awarii możliwe jest poprzez zażądanie nowej instancji usługi poprzez wywołanie I<InterfaceName>.getService() . Jednak ta metoda działa tylko wtedy, gdy proces, który uległ awarii, został ponownie uruchomiony i ponownie zarejestrował swoje usługi w menedżerze usług (co jest ogólnie prawdą w przypadku implementacji HAL).

Klienci interfejsu mogą również zarejestrować odbiorcę śmierci , aby otrzymać powiadomienie w przypadku awarii usługi. Błędy transportu mogą nadal występować, jeśli połączenie zostanie wykonane tuż po śmierci serwera. Aby zarejestrować się w celu otrzymywania takich powiadomień w pobranym interfejsie IFoo , klient może wykonać następujące czynności:

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

Parametr recipient musi być implementacją interfejsu HwBinder.DeathRecipient dostarczonego przez HIDL. Interfejs zawiera pojedynczą metodę serviceDied() , która jest wywoływana, gdy proces obsługujący interfejs umiera.

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

Parametr cookie zawiera plik cookie przekazany wraz z wywołaniem metody linkToDeath() . Możliwe jest także wyrejestrowanie zmarłego po zarejestrowaniu go za pomocą:

foo.unlinkToDeath(recipient);