Di Android 8.0, Android OS dirancang ulang untuk mendefinisikan antarmuka yang jelas
antara platform Android yang tidak bergantung pada perangkat, serta spesifik per perangkat dan vendor
pada kode sumber. Android telah menentukan banyak antarmuka seperti itu dalam bentuk HAL
antarmuka, yang ditentukan sebagai header C di hardware/libhardware
. HIDL
menggantikan antarmuka HAL ini dengan antarmuka
berversi dan stabil, yang dapat
dalam Java (dijelaskan di bawah) atau HIDL sisi klien dan server
antarmuka di C++.
Antarmuka HIDL dimaksudkan untuk digunakan terutama dari kode native, dan sebagai hasil HIDL difokuskan pada pembuatan otomatis kode efisien dalam C++. Namun, Antarmuka HIDL juga harus tersedia untuk digunakan langsung dari Java, karena beberapa Android subsistem (seperti Telepon) memiliki antarmuka HIDL Java.
Halaman di bagian ini menjelaskan frontend Java untuk antarmuka HIDL, menjelaskan cara membuat, mendaftarkan, dan menggunakan layanan, serta menjelaskan cara HAL dan HAL klien yang ditulis dalam Java berinteraksi dengan sistem HIDL RPC.
Contoh klien
Ini adalah contoh klien untuk antarmuka IFoo
dalam paket
android.hardware.foo@1.0
yang terdaftar sebagai nama layanan
default
dan layanan tambahan dengan nama layanan kustom
second_impl
.
Menambahkan library
Anda perlu menambahkan dependensi pada library stub HIDL yang sesuai jika Anda ingin menggunakannya. Biasanya, ini adalah library statis:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Jika Anda tahu bahwa Anda sudah menarik dependensi pada pustaka ini, Anda juga bisa menggunakan penautan bersama:
// in Android.bp libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Pertimbangan tambahan untuk menambahkan library di Android 10
Jika Anda memiliki aplikasi sistem atau vendor yang
menargetkan Android 10 atau yang lebih tinggi,
Anda dapat menyertakan
pustaka-pustaka ini ({i>library<i}) secara statis. Anda juga dapat menggunakan (hanya) kelas HIDL
dari JAR kustom yang diinstal di perangkat dengan API Java stabil yang tersedia
menggunakan mekanisme uses-library
yang ada untuk aplikasi sistem. Tujuan
pendekatan yang kedua akan
menghemat ruang penyimpanan di perangkat. Untuk detail selengkapnya, lihat Mengimplementasikan Library Java SDK. Sebagai
aplikasi yang lebih lama, perilaku lama tetap dipertahankan.
Mulai Android 10, "dangkal" versi dari library ini
juga tersedia. Ini termasuk kelas yang dimaksud, tetapi tidak menyertakan
dari class dependen. Contohnya,
android.hardware.foo-V1.0-java-shallow
menyertakan class di foo
tetapi tidak menyertakan class dalam
android.hidl.base-V1.0-java
, yang berisi class dasar dari semua
Antarmuka HIDL. Jika Anda membuat library yang sudah memiliki opsi
yang tersedia sebagai dependensi, Anda dapat menggunakan kode berikut:
// 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
Library dasar dan pengelola HIDL juga tidak lagi tersedia saat booting
classpath untuk aplikasi (sebelumnya, mereka kadang-kadang digunakan sebagai API tersembunyi, karena
classloader delegasi Android). Sebaliknya, mereka telah dipindahkan ke
namespace dengan jarjar
, dan aplikasi yang menggunakannya (harus sebelum
aplikasi) harus memiliki salinannya sendiri yang terpisah. Modul pada classpath booting menggunakan
HIDL harus menggunakan varian dangkal dari library Java ini dan menambahkan
jarjar_rules: ":framework-jarjar-rules"
ke
Android.bp
untuk menggunakan versi library yang ada
di classpath booting.
Mengubah sumber Java
Hanya ada satu versi (@1.0
) untuk layanan ini, jadi kode ini
hanya mengambil versi tersebut. Lihat
ekstensi antarmuka
untuk mengetahui cara menangani
beberapa versi layanan yang berbeda.
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(…);
Menyediakan layanan
Kode framework di Java mungkin perlu menyajikan antarmuka untuk menerima callback dari HAL.
Untuk antarmuka IFooCallback
di versi 1.0
android.hardware.foo
, Anda dapat menerapkan antarmuka di
Java menggunakan langkah-langkah berikut:
- Menentukan antarmuka Anda di HIDL.
- Buka
/tmp/android/hardware/foo/IFooCallback.java
sebagai alamat IP internal. - Buat modul baru untuk implementasi Java Anda.
- Memeriksa class abstrak
android.hardware.foo.V1_0.IFooCallback.Stub
, lalu tulis class baru untuk memperluasnya dan menerapkan metode abstrak.
Lihat file yang dibuat secara otomatis
Untuk melihat file yang dibuat secara otomatis, jalankan:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
Perintah-perintah ini menghasilkan direktori
/tmp/android/hardware/foo/1.0
. Untuk file
hardware/interfaces/foo/1.0/IFooCallback.hal
, tindakan ini akan menghasilkan
file /tmp/android/hardware/foo/1.0/IFooCallback.java
, yang
melakukan enkapsulasi antarmuka Java, kode {i>proxy<i}, dan stub (baik {i>proxy<i} maupun
stub yang sesuai dengan antarmuka).
-Lmakefile
membuat aturan yang menjalankan perintah ini di build
waktu dan memungkinkan
Anda untuk menyertakan
android.hardware.foo-V1.0-java
dan tautkan ke
file yang sesuai. Skrip yang secara otomatis melakukan ini
untuk proyek yang penuh dengan
antarmuka dapat ditemukan di hardware/interfaces/update-makefiles.sh
.
Jalur dalam contoh ini bersifat relatif; hardware/antarmuka dapat bersifat sementara
di bawah hierarki kode agar Anda dapat mengembangkan HAL sebelum
memublikasikannya.
Menjalankan layanan
HAL menyediakan antarmuka IFoo
, yang harus membuat
callback ke framework melalui antarmuka IFooCallback
. Tujuan
Antarmuka IFooCallback
tidak terdaftar dengan nama sebagai antarmuka yang dapat ditemukan
layanan; sebagai gantinya, IFoo
harus berisi metode seperti
setFooCallback(IFooCallback x)
.
Untuk menyiapkan IFooCallback
dari versi 1.0
Paket android.hardware.foo
, tambahkan
android.hardware.foo-V1.0-java
ke Android.mk
. Kode
menjalankan layanan ini adalah:
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);
Ekstensi antarmuka
Dengan asumsi layanan tertentu mengimplementasikan antarmuka IFoo
di semua
di perangkat tertentu, layanan itu mungkin menyediakan
kemampuan tambahan yang diimplementasikan
dalam ekstensi antarmuka
IBetterFoo
, sebagai berikut:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Memanggil kode yang menyadari antarmuka yang diperluas bisa menggunakan
Metode Java castFrom()
untuk mentransmisikan antarmuka dasar dengan aman ke
antarmuka yang diperluas:
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. }