Esta seção detalha métodos e erros de interface.
Métodos vazios
Métodos que não retornam resultados são convertidos 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 convertidos em seus equivalentes Java também retornando 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 vários 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 ao 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 callback…
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 o terceiro parâmetro para oneProducesTwoThings()
.
Erros de transporte e destinatários da morte
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 morto 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, esse método funciona apenas se o processo que travou foi reiniciado e registrou novamente seus serviços com o servicemanager (o que geralmente é verdade para implementações de HAL).
Os clientes de uma interface também podem registrar um destinatário de falecimento para receber uma notificação quando um serviço morre. Erros de transporte ainda podem ocorrer se uma chamada for feita assim que o servidor morrer. Para se registrar para essas notificações em uma interface IFoo
recuperada, um cliente pode fazer o seguinte:
foo.linkToDeath(recipient, 1481 /* cookie */);
O parâmetro de 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 falecimento após registrá-lo usando:
foo.unlinkToDeath(recipient);