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

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

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

Методы, которые не возвращают результаты, преобразуются в методы 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);