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

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

Методы void

Методы, которые не возвращают результаты, преобразуются в методы 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(). Однако этот метод работает, только если процесс, в котором произошел сбой, перезапустился и повторно зарегистрировал свои сервисы в servicemanager (что обычно верно для реализаций 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);