In Android 8.0, il sistema operativo Android è stato riprogettato per definire interfacce chiare
tra la piattaforma Android indipendente dal dispositivo e quella specifica del fornitore e del dispositivo
le API nel tuo codice. Android ha già definito molte interfacce di questo tipo sotto forma di HAL
interfacce definite come intestazioni C in hardware/libhardware
. HIDL
ha sostituito queste interfacce HAL con interfacce stabili con controllo delle versioni,
in Java (descritto di seguito) o sul lato client e lato server HIDL
interfacce in C++.
Le interfacce HIDL sono progettate per essere utilizzate principalmente da codice nativo e come risultato HIDL è incentrato sulla generazione automatica di codice efficiente in C++. Tuttavia, Le interfacce HIDL devono inoltre essere disponibili per l'utilizzo direttamente da Java, poiché alcuni modelli sottosistemi (come la telefonia) hanno interfacce Java HIDL.
Le pagine di questa sezione descrivono il frontend Java per le interfacce HIDL, descrivere in dettaglio come creare, registrare e utilizzare i servizi e spiegare come gli HAL e HAL I client scritti in Java interagiscono con il sistema RPC HIDL.
Esempio di client
Questo è un esempio di client per un'interfaccia IFoo
nel pacchetto
android.hardware.foo@1.0
registrato come nome di servizio
default
e un servizio aggiuntivo con il nome del servizio personalizzato
second_impl
.
Aggiungi librerie
È necessario aggiungere dipendenze nella libreria stub HIDL corrispondente se vuoi usarlo. Di solito, si tratta di una libreria statica:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Se sai già che stai estraendo le dipendenze da queste librerie, puoi anche usare il collegamento condiviso:
// in Android.bp libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Considerazioni aggiuntive per l'aggiunta di librerie in Android 10
Se hai un'app di sistema o di un fornitore che ha come target Android 10 o versioni successive:
puoi includere le librerie in modo statico. Puoi anche utilizzare (solo) classi HIDL
da JAR personalizzati installati sul dispositivo con API Java stabili rese disponibili
utilizzando il meccanismo uses-library
esistente per le app di sistema. La
quest'ultimo consente di risparmiare spazio sul dispositivo. Per maggiori dettagli, consulta Implementazione della libreria SDK Java. Per
per le app meno recenti, viene mantenuto il comportamento precedente.
A partire da Android 10, "shallow" di queste librerie
. Sono inclusi il corso in questione, ma non nessuno
delle classi dipendenti. Ad esempio,
android.hardware.foo-V1.0-java-shallow
include corsi nel file foo
ma non include classi in
android.hidl.base-V1.0-java
, che contiene la classe base di tutti
Interfacce HIDL. Se stai creando una libreria che contiene già i preferiti
disponibili come dipendenza, puoi usare quanto segue:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java-shallow", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java-shallow
Inoltre, le librerie di base e gestore HIDL non sono più disponibili all'avvio
classpath per le app (in precedenza, a volte venivano utilizzate come API nascoste)
classloader, delegato di Android). Sono stati invece spostati in un nuovo
con jarjar
e le app che ne usano (necessariamente priv
app) devono avere copie separate. per i moduli sul classpath di avvio
L'HIDL deve usare le varianti superficiali di queste librerie Java e aggiungere
jarjar_rules: ":framework-jarjar-rules"
al suo
Android.bp
per utilizzare la versione di queste librerie esistente
nel classpath di avvio.
Modifica il tuo codice sorgente Java
Esiste una sola versione (@1.0
) di questo servizio, quindi questo codice
recupera solo quella versione. Consulta
estensioni di interfaccia
su come gestire più versioni diverse del servizio.
import android.hardware.foo.V1_0.IFoo; ... // retry to wait until the service starts up if it is in the manifest IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available IFoo anotherServer = IFoo.getService("second_impl", true /* retry */); server.doSomething(…);
Fornire un servizio
Il codice framework in Java potrebbe dover gestire le interfacce per ricevere dagli HAL.
Per l'interfaccia IFooCallback
nella versione 1.0 di
android.hardware.foo
, puoi implementare l'interfaccia
utilizzando la seguente procedura:
- Definisci l'interfaccia in HIDL.
- Apri
/tmp/android/hardware/foo/IFooCallback.java
come riferimento. - Crea un nuovo modulo per l'implementazione Java.
- Esaminare la classe astratta
android.hardware.foo.V1_0.IFooCallback.Stub
, quindi scrivi un nuovo corso per estenderlo e implementare i metodi astratti.
Visualizza i file generati automaticamente
Per visualizzare i file generati automaticamente, esegui:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
Questi comandi generano la directory
/tmp/android/hardware/foo/1.0
. Per il file
hardware/interfaces/foo/1.0/IFooCallback.hal
, questo genera
file /tmp/android/hardware/foo/1.0/IFooCallback.java
, che
incapsula l’interfaccia Java, il codice proxy e gli stub (sia
stub sono conformi all'interfaccia).
-Lmakefile
genera le regole che eseguono questo comando al momento della build
e ti consentono di includere
android.hardware.foo-V1.0-java
e collega alla
i file appropriati. Uno script che esegue questa operazione automaticamente per un progetto pieno di
disponibili all'indirizzo hardware/interfaces/update-makefiles.sh
.
In questo esempio, i percorsi sono relativi; hardware/interfacce può essere una soluzione
sotto la struttura del codice per consentirti di sviluppare un HAL prima
la pubblicazione.
Esegui un servizio
L'HAL fornisce l'interfaccia IFoo
, che deve rendere asincrono
al framework tramite l'interfaccia IFooCallback
. La
L'interfaccia di IFooCallback
non è registrata per nome come rilevabile
servizio; invece, IFoo
deve contenere un metodo come
setFooCallback(IFooCallback x)
.
Per configurare IFooCallback
dalla versione 1.0 di
Pacchetto android.hardware.foo
, aggiungi
android.hardware.foo-V1.0-java
a Android.mk
. Il codice
per eseguire il servizio è:
import android.hardware.foo.V1_0.IFoo; import android.hardware.foo.V1_0.IFooCallback.Stub; .... class FooCallback extends IFooCallback.Stub { // implement methods } .... // Get the service from which you will be receiving callbacks. // This also starts the threadpool for your callback service. IFoo server = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available .... // This must be a persistent instance variable, not local, // to avoid premature garbage collection. FooCallback mFooCallback = new FooCallback(); .... // Do this once to create the callback service and tell the "foo-bar" service server.setFooCallback(mFooCallback);
Estensioni interfaccia
Presumendo che un determinato servizio implementi l'interfaccia IFoo
in tutte
su un dispositivo specifico, è possibile che il servizio
funzionalità aggiuntive implementate nell'estensione di interfaccia
IBetterFoo
, come segue:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Il codice di chiamata che conosce l'interfaccia estesa può utilizzare il
castFrom()
metodo Java per trasmettere in sicurezza l'interfaccia di base all'account
dell'interfaccia estesa:
IFoo baseService = IFoo.getService(true /* retry */); // throws NoSuchElementException if not available IBetterFoo extendedService = IBetterFoo.castFrom(baseService); if (extendedService != null) { // The service implements the extended interface. } else { // The service implements only the base interface. }