Esta seção detalha métodos e erros de interface.
Métodos vazios
Os métodos que não retornam resultados são traduzidos em métodos Java que retornam void
. Por exemplo, a declaração HIDL:
doThisWith(float param);
… torna-se:
void doThisWith(float param);
Métodos de resultado único
Métodos que retornam um único resultado são traduzidos em seus equivalentes Java, retornando também um único resultado. Por exemplo, o seguinte:
doQuiteABit(int32_t a, int64_t b, float c, double d) generates (double something);
… torna-se:
double doQuiteABit(int a, long b, float c, double d);
Métodos de múltiplos resultados
Para cada método que retorna mais de um resultado, é gerada uma classe de callback que fornece todos os resultados em seu método onValues
. Esse retorno de chamada atua como um parâmetro adicional para o método. Por exemplo, o seguinte:
oneProducesTwoThings(SomeEnum x) generates (double a, double b);
… torna-se:
public interface oneProducesTwoThingsCallback { public void onValues(double a, double b); } void oneProducesTwoThings(byte x, oneProducesTwoThingsCallback cb);
Um chamador de oneProducesTwoThings()
normalmente usaria uma classe interna anônima ou lambda para implementar o retorno de chamada localmente:
someInstanceOfFoo.oneProducesTwoThings( 5 /* x */, new IFoo.oneProducesTwoThingsCallback() { @Override void onValues(double a, double b) { // do something interesting with a and b. ... }});
ou:
someInstanceOfFoo.oneProducesTwoThings(5 /* x */, (a, b) -> a > 3.0 ? f(a, b) : g(a, b)));
Você também pode definir uma classe para usar como retorno de chamada…
class MyCallback implements oneProducesTwoThingsCallback { public void onValues(double a, double b) { // do something interesting with a and b. } }
… e passe uma instância de MyCallback
como terceiro parâmetro para oneProducesTwoThings()
.
Erros de transporte e destinatários de óbito
Como as implementações de serviço podem ser executadas em um processo diferente, em alguns casos o cliente pode permanecer ativo mesmo quando o processo que implementa uma interface morre. Chamadas em um objeto de interface hospedado em um processo inativo falham com um erro de transporte (uma exceção de tempo de execução lançada pelo método chamado). A recuperação de tal falha é possível solicitando uma nova instância do serviço chamando I<InterfaceName>.getService()
. No entanto, este método funciona apenas se o processo que travou tiver reiniciado e registrado novamente seus serviços no servicemanager (o que geralmente é verdadeiro para implementações HAL).
Os clientes de uma interface também podem registrar um destinatário de falecimento para receber uma notificação quando um serviço morrer. Erros de transporte ainda podem ocorrer se uma chamada for feita no momento em que o servidor morre. Para registrar essas notificações em uma interface IFoo
recuperada, um cliente pode fazer o seguinte:
foo.linkToDeath(recipient, 1481 /* cookie */);
O parâmetro recipient
deve ser uma implementação da interface HwBinder.DeathRecipient
fornecida pelo HIDL. A interface contém um único método serviceDied()
que é chamado quando o processo que hospeda a interface morre.
final class DeathRecipient implements HwBinder.DeathRecipient { @Override public void serviceDied(long cookie) { // Deal with service going away } }
O parâmetro cookie
contém o cookie que foi passado com a chamada para linkToDeath()
. Também é possível cancelar o registro de um beneficiário de óbito após registrá-lo usando:
foo.unlinkToDeath(recipient);