Questa sezione descrive in dettaglio i metodi e gli errori dell'interfaccia.
Metodi void
I metodi che non restituiscono risultati vengono tradotti in metodi Java che
retituan void
. Ad esempio, la dichiarazione HIDL:
doThisWith(float param);
… diventa:
void doThisWith(float param);
Metodi con un solo risultato
I metodi che restituiscono un singolo risultato vengono tradotti nei relativi equivalenti Java che restituiscono anche un singolo risultato. Ad esempio:
doQuiteABit(int32_t a, int64_t b, float c, double d) generates (double something);
… diventa:
double doQuiteABit(int a, long b, float c, double d);
Metodi con più risultati
Per ogni metodo che restituisce più di un risultato, viene generata una classe di callback che fornisce tutti i risultati nel relativo metodo onValues
.
Questo callback funge da parametro aggiuntivo per il metodo. Ad esempio, quanto segue:
oneProducesTwoThings(SomeEnum x) generates (double a, double b);
… diventa:
public interface oneProducesTwoThingsCallback { public void onValues(double a, double b); } void oneProducesTwoThings(byte x, oneProducesTwoThingsCallback cb);
Un chiamante di oneProducesTwoThings()
in genere utilizza un
classe interna o lambda anonima per implementare il callback localmente:
someInstanceOfFoo.oneProducesTwoThings( 5 /* x */, new IFoo.oneProducesTwoThingsCallback() { @Override void onValues(double a, double b) { // do something interesting with a and b. ... }});
oppure:
someInstanceOfFoo.oneProducesTwoThings(5 /* x */, (a, b) -> a > 3.0 ? f(a, b) : g(a, b)));
Puoi anche definire una classe da utilizzare come callback…
class MyCallback implements oneProducesTwoThingsCallback { public void onValues(double a, double b) { // do something interesting with a and b. } }
… e passa un'istanza di MyCallback
come terzo parametro a
oneProducesTwoThings()
.
Errori di trasporto e destinatari decessi
Poiché le implementazioni dei servizi possono essere eseguite in un processo diverso, in alcuni casi il client può rimanere attivo anche quando il processo che implementa un'interfaccia termina.
Le chiamate a un oggetto interfaccia ospitato in un processo non attivo non vanno a buon fine con un errore di trasporto (un'eccezione di runtime lanciata dal metodo chiamato). È possibile recuperare da questo tipo di errore richiedendo una nuova istanza del servizio chiamando I<InterfaceName>.getService()
. Tuttavia, questo metodo funziona solo se il processo che ha avuto un arresto anomalo è stato riavviato e ha registrato di nuovo i suoi servizi con il servicemanager (il che è generalmente vero per le implementazioni HAL).
I client di un'interfaccia possono anche registrare un destinatario per i messaggi di morte per ricevere una notifica quando un servizio non è più disponibile. Gli errori di trasporto possono comunque verificarsi se viene effettuata una chiamata proprio quando il server si arresta in modo anomalo. Per registrarsi a queste notifiche su un'interfaccia IFoo
recuperata, un client può:
foo.linkToDeath(recipient, 1481 /* cookie */);
Il parametro recipient
deve essere un'implementazione dell'interfaccia HwBinder.DeathRecipient
fornita da HIDL. L'interfaccia contiene un singolo metodo serviceDied()
che viene chiamato quando il processo che ospita l'interfaccia termina.
final class DeathRecipient implements HwBinder.DeathRecipient { @Override public void serviceDied(long cookie) { // Deal with service going away } }
Il parametro cookie
contiene il cookie passato con la chiamata a linkToDeath()
. È anche possibile annullare la registrazione di un destinatario
in caso di decesso dopo averlo registrato utilizzando:
foo.unlinkToDeath(recipient);