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