W Androidzie 8.0 zmieniono architekturę systemu operacyjnego Android, aby zdefiniować przejrzyste interfejsy
między platformą Android niezależnie od urządzenia a modelem urządzenia i dostawcy,
w kodzie. Wiele takich interfejsów w Androidzie zostały już zdefiniowane w postaci HAL.
interfejsów zdefiniowanych jako nagłówki C w hardware/libhardware
. HIDL
te interfejsy HAL zostały zastąpione stabilnymi, wersjonowanymi interfejsami, które mogą
być w języku Java (opisany poniżej) lub HIDL po stronie klienta i serwera
w C++.
Interfejsy HIDL są przeznaczone przede wszystkim do stosowania w kodzie natywnym oraz jako W efekcie HIDL koncentruje się na automatycznym generowaniu wydajnego kodu w języku C++. Pamiętaj jednak: Interfejsy HIDL muszą być również dostępne do użycia bezpośrednio w języku Java, jak niektóre platformy Android podsystemy (np. Telefonia) mają interfejsy HIDL w Javie.
Na stronach w tej sekcji opisaliśmy frontend Java dla interfejsów HIDL, jak tworzyć, rejestrować i korzystać z usług oraz wyjaśnić, jak HAL i HAL Klienty napisane w Javie współdziałają z systemem RPC HIDL.
Przykład klienta
To jest przykład klienta interfejsu IFoo
w pakiecie
android.hardware.foo@1.0
, która jest zarejestrowana jako nazwa usługi
default
i usługa dodatkowa o niestandardowej nazwie usługi
second_impl
Dodaj biblioteki
Musisz dodać zależności od odpowiedniej biblioteki skróconej HIDL, jeśli chcesz go używać. Zwykle jest to biblioteka statyczna:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Jeśli wiesz, że pobierasz już zależności od tych bibliotek, można też użyć udostępnionego linku:
// in Android.bp libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Dodatkowe uwagi na temat dodawania bibliotek w Androidzie 10
Jeśli masz aplikację systemową lub aplikację dostawcy przeznaczoną na Androida 10 lub nowszego,
możesz statycznie uwzględnić te biblioteki. Możesz też korzystać tylko z zajęć HIDL
z niestandardowych plików JAR zainstalowanych na urządzeniu z udostępnionymi stabilnymi interfejsami API Java
za pomocą istniejącego mechanizmu uses-library
w przypadku aplikacji systemowych.
pozwala zaoszczędzić miejsce na urządzeniu. Więcej informacji znajdziesz w artykule Wdrażanie biblioteki pakietu SDK Java. Dla:
starszych aplikacji, zostaje zachowany stary sposób działania.
Od Androida 10 („płytki”) wersji tych bibliotek
. obejmują one kwestionowane zajęcia, ale nie zawierają żadnych
klas zależnych. Przykład:
android.hardware.foo-V1.0-java-shallow
obejmuje zajęcia w aplikacji
pakiet, ale nie zawiera klas w
android.hidl.base-V1.0-java
, która zawiera klasę bazową wszystkich
Interfejsy HIDL. Jeśli tworzysz bibliotekę, w której jest już preferowany
klas podstawowych interfejsu są dostępne jako zależność, możesz użyć następującego kodu:
// 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
Biblioteki podstawowe i menedżera HIDL nie są już dostępne podczas uruchamiania.
classpath aplikacji (wcześniej były one czasem używane jako ukryte interfejsy API ze względu na
w przypadku Androida z przekazywaniem dostępu w pierwszej kolejności). Zostały one przeniesione do nowego
przestrzeni nazw z atrybutem jarjar
oraz aplikacje, które z nich korzystają (niezbędne
aplikacje) muszą mieć oddzielne kopie. Moduły w ścieżce klasy rozruchowej za pomocą funkcji
HIDL musi używać płytkich wersji tych bibliotek Java i dodawać
jarjar_rules: ":framework-jarjar-rules"
na ich
Android.bp
, aby używać istniejących wersji tych bibliotek
w ścieżce klasy uruchamiania.
Modyfikowanie źródła w Javie
Ta usługa istnieje tylko w jednej wersji (@1.0
), więc ten kod
pobiera tylko tę wersję. Zobacz
rozszerzenia interfejsu
, aby dowiedzieć się, jak obsługiwać różne wersje usługi.
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(…);
Świadczenie usługi
Kod platformy w Javie może wymagać obsługi interfejsów, aby otrzymywać asynchroniczne wywołań zwrotnych z list HAL.
Dla interfejsu IFooCallback
w wersji 1.0
android.hardware.foo
, możesz wdrożyć swój interfejs w
w Javie, wykonując te czynności:
- Zdefiniuj interfejs w HIDL.
- Otwórz aplikację
/tmp/android/hardware/foo/IFooCallback.java
jako odwołania. - Utwórz nowy moduł implementacji w języku Java.
- Przeanalizuj klasę abstrakcyjną
android.hardware.foo.V1_0.IFooCallback.Stub
, a następnie napisz nowe zajęcia aby ją rozszerzyć i wdrożyć metody abstrakcyjne.
Wyświetl pliki wygenerowane automatycznie
Aby wyświetlić automatycznie wygenerowane pliki, uruchom polecenie:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
Te polecenia generują katalog
/tmp/android/hardware/foo/1.0
W przypadku pliku
hardware/interfaces/foo/1.0/IFooCallback.hal
, generuje
plik /tmp/android/hardware/foo/1.0/IFooCallback.java
, który
otacza interfejs Java, kod serwera proxy i namioty (zarówno proxy, jak i
aktówki są zgodne z interfejsem).
-Lmakefile
generuje reguły, które uruchamiają to polecenie podczas kompilacji
i umieszczać w nim
android.hardware.foo-V1.0-java
i zawiera link do
odpowiednie pliki. Skrypt, który robi to automatycznie w przypadku projektu pełnego
pod adresem hardware/interfaces/update-makefiles.sh
.
Ścieżki w tym przykładzie są względne, sprzęt/interfejsy mogą być tymczasowym
w drzewie kodu, aby umożliwić opracowanie kodu HAL przed
podczas publikacji.
Uruchom usługę
HAL udostępnia interfejs IFoo
, który musi być asynchroniczny
wywołania zwrotne do platformy w interfejsie IFooCallback
.
Interfejs IFooCallback
nie jest zarejestrowany z nazwy jako wykrywalny
Service; zamiast tego IFoo
musi zawierać metodę, taką jak
setFooCallback(IFooCallback x)
Aby skonfigurować IFooCallback
z wersji 1.0
pakiet android.hardware.foo
, dodaj
android.hardware.foo-V1.0-java
do Android.mk
. Kod
aby uruchomić usługę:
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);
Rozszerzenia interfejsu
Przy założeniu, że dana usługa implementuje interfejs IFoo
we wszystkich
na określonych urządzeniach może być ona udostępniana
dodatkowe możliwości zaimplementowane w rozszerzeniu interfejsu
IBetterFoo
w następujący sposób:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Kod połączenia znający rozszerzony interfejs może używać funkcji
Metoda Java castFrom()
do bezpiecznego przesyłania interfejsu podstawowego na
rozszerzony interfejs:
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. }