Методы интерфейса и ошибки

В этом разделе подробно описаны методы интерфейса и ошибки.

Пустые методы

Методы, не возвращающие результатов, транслируются в методы Java, возвращающие void . Например, объявление HIDL:

doThisWith(float param);

… становится:

void doThisWith(float param);

Методы с одним результатом

Методы, возвращающие один результат, переводятся в их эквиваленты в Java, также возвращающие один результат. Например, следующее:

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

… становится:

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

Методы с несколькими результатами

Для каждого метода, который возвращает более одного результата, создается класс обратного вызова, который предоставляет все результаты в своем методе onValues . Этот обратный вызов действует как дополнительный параметр метода. Например, следующее:

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

… становится:

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

Вызывающий oneProducesTwoThings() обычно использует анонимный внутренний класс или лямбду для локальной реализации обратного вызова:

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

или же:

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

Вы также можете определить класс для использования в качестве обратного вызова…

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

… и передать экземпляр MyCallback в качестве третьего параметра oneProducesTwoThings() .

Транспортные ошибки и смерти получателей

Поскольку реализации службы могут выполняться в другом процессе, в некоторых случаях клиент может оставаться в живых, даже когда процесс, реализующий интерфейс, умирает. Вызовы объекта интерфейса, размещенного в мертвом процессе, завершаются с ошибкой транспорта (исключение во время выполнения, вызванное вызываемым методом). Восстановление после такого сбоя возможно путем запроса нового экземпляра службы с помощью вызова I<InterfaceName>.getService() . Однако этот метод работает только в том случае, если процесс, в котором произошел сбой, был перезапущен и повторно зарегистрировал свои службы в диспетчере служб (что обычно верно для реализаций HAL).

Клиенты интерфейса также могут зарегистрировать получателя смерти , чтобы получать уведомление, когда служба умирает. Ошибки транспорта все еще могут возникать, если вызов выполняется сразу после того, как сервер умирает. Чтобы зарегистрироваться для получения таких уведомлений на полученном интерфейсе IFoo , клиент может сделать следующее:

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

Параметр recipient должен быть реализацией интерфейса HwBinder.DeathRecipient , предоставляемого HIDL. Интерфейс содержит единственный метод serviceDied() , который вызывается, когда умирает процесс, в котором находится интерфейс.

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

Параметр cookie содержит файл cookie, который был передан при вызове linkToDeath() . Также можно отменить регистрацию получателя смерти после его регистрации, используя:

foo.unlinkToDeath(recipient);