In Android 8.0 wurde die Architektur des Android-Betriebssystems umgestaltet, um klare Schnittstellen zu definieren.
zwischen der geräteunabhängigen Android-Plattform und den geräte- und anbieterspezifischen
Code. Android hat bereits viele dieser Schnittstellen in Form von HAL definiert.
Schnittstellen, die in hardware/libhardware
als C-Header definiert sind. HIDL
diese HAL-Schnittstellen durch stabile, versionierte Schnittstellen ersetzt wurden,
entweder in Java (siehe Beschreibung unten) oder clientseitiges und serverseitiges HIDL
Schnittstellen in C++.
HIDL-Schnittstellen werden hauptsächlich aus nativem Code verwendet und Ergebnis-HIDL konzentriert sich auf die automatische Generierung von effizientem Code in C++. Sie können jedoch HIDL-Schnittstellen müssen auch für die direkte Verwendung in Java verfügbar sein, da einige Android- Subsysteme (z. B. Telefonie) verfügen über Java HIDL-Schnittstellen.
Die Seiten in diesem Abschnitt beschreiben das Java-Front-End für HIDL-Schnittstellen. Erläutern, wie Dienste erstellt, registriert und genutzt werden und wie HALs und HAL funktionieren In Java geschriebene Clients interagieren mit dem HIDL RPC-System.
Kundenbeispiel
Dies ist ein Beispiel eines Clients für die Schnittstelle IFoo
im Paket
android.hardware.foo@1.0
, die als Dienstname registriert ist
default
und ein zusätzlicher Dienst mit dem benutzerdefinierten Dienstnamen
second_impl
.
Bibliotheken hinzufügen
Sie müssen Abhängigkeiten zur entsprechenden HIDL-Stub-Bibliothek hinzufügen, wenn die Sie verwenden möchten. Normalerweise ist dies eine statische Bibliothek:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Wenn Sie wissen, dass Sie bereits Abhängigkeiten von diesen Bibliotheken abrufen, kann auch eine freigegebene Verknüpfung verwenden:
// in Android.bp libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Weitere Überlegungen zum Hinzufügen von Bibliotheken in Android 10
Wenn Sie eine System- oder Anbieter-App haben,
die auf Android 10 oder höher ausgerichtet ist,
können Sie diese Bibliotheken statisch einbinden. Sie können auch (nur) HIDL-Klassen verwenden
aus benutzerdefinierten JARs, die auf dem Gerät mit stabilen Java-APIs installiert sind
Dabei wird der vorhandene Mechanismus uses-library
für System-Apps verwendet. Die
spart Speicherplatz auf dem Gerät. Weitere Informationen finden Sie unter Java SDK-Bibliothek implementieren. Für
älteren Apps verwendet wird, bleibt das alte Verhalten erhalten.
Ab Android 10 „oberflächlich“ Versionen dieser Bibliotheken
sind ebenfalls verfügbar. Dazu gehören der betreffende Kurs, aber keine
der abhängigen Klassen gibt. Beispiel:
android.hardware.foo-V1.0-java-shallow
enthält Klassen in foo.
-Paket enthält, jedoch keine Klassen in
android.hidl.base-V1.0-java
, die die Basisklasse aller
HIDL-Schnittstellen Wenn Sie eine Bibliothek erstellen, die bereits die bevorzugte
als Abhängigkeit zur Verfügung stehen, können Sie Folgendes verwenden:
// 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
HIDL-Basis- und Managerbibliotheken sind ebenfalls beim Booten nicht mehr verfügbar
Klassenpfad für Apps (bisher wurden sie manchmal als verborgene API verwendet,
Delegat-First-Classloader von Android). Stattdessen wurden sie in eine neue
Namespace mit jarjar
und Anwendungen, die diese verwenden (unbedingt priv
Apps) müssen separate Kopien haben. Module im Boot-Klassenpfad mithilfe von
HIDL muss die oberflächlichen Varianten dieser Java-Bibliotheken verwenden und
jarjar_rules: ":framework-jarjar-rules"
zu ihrem/seinem
Android.bp
, um die vorhandene Version dieser Bibliotheken zu verwenden
im Boot-Klassenpfad.
Java-Quelle modifizieren
Es gibt nur eine Version (@1.0
) dieses Dienstes, daher wird dieser Code
ruft nur diese Version ab. Weitere Informationen finden Sie unter
Erweiterungen für die Benutzeroberfläche
.
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(…);
Dienst bereitstellen
Framework-Code in Java muss möglicherweise Schnittstellen bereitstellen, um asynchrone Rückrufen von HALs.
Für die IFooCallback
-Schnittstelle in Version 1.0 des
android.hardware.foo
-Pakets enthält, können Sie Ihre Schnittstelle implementieren in
Gehen Sie dazu so vor:
- Definieren Sie Ihre Schnittstelle in HIDL.
/tmp/android/hardware/foo/IFooCallback.java
öffnen als Referenz.- Erstellen Sie ein neues Modul für Ihre Java-Implementierung.
- Die abstrakte Klasse untersuchen
android.hardware.foo.V1_0.IFooCallback.Stub
und anschließend einen neuen Kurs schreiben um sie zu erweitern und abstrakte Methoden zu implementieren.
Automatisch generierte Dateien ansehen
Führen Sie folgenden Befehl aus, um die automatisch generierten Dateien aufzurufen:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
Mit diesen Befehlen wird das Verzeichnis
/tmp/android/hardware/foo/1.0
Für die Datei
hardware/interfaces/foo/1.0/IFooCallback.hal
generiert die
Datei /tmp/android/hardware/foo/1.0/IFooCallback.java
, die
kapselt die Java-Schnittstelle, den Proxy-Code und die Stubs (sowohl Proxy-
-Stubs entsprechen der -Schnittstelle).
-Lmakefile
generiert die Regeln, die diesen Befehl beim Build ausführen
Zeit und ermöglichen es Ihnen,
android.hardware.foo-V1.0-java
und verknüpfen Sie sie mit dem
die entsprechenden Dateien. Ein Skript, das dies für ein Projekt mit vielen
finden Sie unter hardware/interfaces/update-makefiles.sh
.
Die Pfade in diesem Beispiel sind relativ. Hardware/Schnittstellen können temporäre
unter Ihrer Codestruktur, damit Sie eine HAL vor der
bei der Veröffentlichung.
Dienst ausführen
Der HAL stellt die IFoo
-Schnittstelle bereit, die eine asynchrone
Callbacks an das Framework über die IFooCallback
-Schnittstelle. Die
Die IFooCallback
-Schnittstelle ist namentlich nicht als sichtbar registriert
Service; Stattdessen muss IFoo
eine Methode wie
setFooCallback(IFooCallback x)
Zum Einrichten von IFooCallback
aus Version 1.0 des
android.hardware.foo
Paket, hinzufügen
android.hardware.foo-V1.0-java
bis Android.mk
. Der Code
zum Ausführen des Dienstes ist:
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);
Erweiterungen der Benutzeroberfläche
Wenn ein bestimmter Dienst die IFoo
-Schnittstelle für alle
kann es passieren, dass der Dienst auf einem bestimmten Gerät
zusätzliche Funktionen, die in der Erweiterung für die Benutzeroberfläche implementiert wurden
IBetterFoo
:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Ein Aufrufcode, der die erweiterte Oberfläche berücksichtigt, kann die Funktion
castFrom()
-Java-Methode, um die Basisschnittstelle sicher in den
erweiterte Oberfläche:
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. }