Di Android 8.0, OS Android dirancang ulang untuk mendefinisikan antarmuka yang jelas antara platform Android yang tidak bergantung pada perangkat, serta kode khusus perangkat dan vendor. Android telah mendefinisikan banyak antarmuka seperti itu dalam bentuk antarmuka HAL, yang didefinisikan sebagai header C di hardware/libhardware
. HIDL menggantikan antarmuka HAL ini dengan antarmuka berversi yang stabil, yang dapat menggunakan Java (dijelaskan di bawah) atau menjadi antarmuka HIDL sisi klien dan server dalam C++ .
Antarmuka HIDL dimaksudkan untuk digunakan terutama dari kode asli, dan sebagai hasilnya HIDL difokuskan pada pembuatan kode efisien secara otomatis di C++. Namun, antarmuka HIDL juga harus tersedia untuk digunakan langsung dari Java, karena beberapa subsistem Android (seperti Telephony) memiliki antarmuka Java HIDL.
Halaman-halaman di bagian ini menjelaskan frontend Java untuk antarmuka HIDL, merinci cara membuat, mendaftar, dan menggunakan layanan, dan menjelaskan bagaimana klien HAL dan HAL yang ditulis dalam Java berinteraksi dengan sistem HIDL RPC.
Menjadi 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 perpustakaan
Anda perlu menambahkan dependensi pada perpustakaan rintisan HIDL yang sesuai jika Anda ingin menggunakannya. Biasanya, ini adalah perpustakaan 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 tautan 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 perpustakaan di Android 10
Jika Anda memiliki aplikasi sistem atau vendor yang menargetkan Android 10 atau lebih tinggi, Anda bisa menyertakan pustaka ini secara statis. Anda juga dapat menggunakan (hanya) kelas HIDL dari JAR khusus yang diinstal pada perangkat dengan Java API stabil yang tersedia menggunakan mekanisme uses-library
yang ada untuk aplikasi sistem. Pendekatan terakhir menghemat ruang pada perangkat. Untuk detail selengkapnya, lihat Menerapkan Java SDK Library . Untuk aplikasi lama, perilaku lama dipertahankan.
Mulai Android 10, versi "dangkal" dari pustaka ini juga tersedia. Ini termasuk kelas yang dimaksud tetapi tidak termasuk kelas dependen mana pun. Misalnya, android.hardware.foo-V1.0-java-shallow
menyertakan kelas dalam paket foo, namun tidak menyertakan kelas dalam android.hidl.base-V1.0-java
, yang berisi kelas dasar dari semua HIDL antarmuka. Jika Anda membuat perpustakaan yang sudah memiliki kelas dasar antarmuka pilihan yang tersedia sebagai dependensi, Anda dapat menggunakan yang berikut ini:
// 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
Pustaka dasar dan pengelola HIDL juga tidak lagi tersedia di jalur kelas boot untuk aplikasi (sebelumnya, terkadang digunakan sebagai API tersembunyi, karena pemuat kelas yang mengutamakan delegasi Android). Sebaliknya, mereka telah dipindahkan ke namespace baru dengan jarjar
, dan aplikasi yang menggunakan ini (tentu saja aplikasi priv) harus memiliki salinan terpisah. Modul pada classpath boot yang menggunakan HIDL harus menggunakan varian dangkal dari pustaka Java ini dan menambahkan jarjar_rules: ":framework-jarjar-rules"
ke Android.bp
untuk menggunakan versi pustaka yang ada di classpath boot.
Memodifikasi sumber Java Anda
Hanya ada satu versi ( @1.0
) dari 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(…);
Memberikan layanan
Kode kerangka kerja di Java mungkin perlu melayani antarmuka untuk menerima panggilan balik asinkron dari HAL.
Untuk antarmuka IFooCallback
dalam paket android.hardware.foo
versi 1.0, Anda dapat mengimplementasikan antarmuka Anda di Java menggunakan langkah-langkah berikut:
- Tentukan antarmuka Anda di HIDL.
- Buka
/tmp/android/hardware/foo/IFooCallback.java
sebagai referensi. - Buat modul baru untuk implementasi Java Anda.
- Periksa kelas abstrak
android.hardware.foo.V1_0.IFooCallback.Stub
, lalu tulis kelas baru untuk memperluasnya dan mengimplementasikan metode abstrak.
Melihat 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 ini menghasilkan direktori /tmp/android/hardware/foo/1.0
. Untuk file hardware/interfaces/foo/1.0/IFooCallback.hal
, ini menghasilkan file /tmp/android/hardware/foo/1.0/IFooCallback.java
, yang merangkum antarmuka Java, kode proxy, dan stub (keduanya proxy dan rintisan sesuai dengan antarmuka).
-Lmakefile
menghasilkan aturan yang menjalankan perintah ini pada waktu build dan memungkinkan Anda menyertakan android.hardware.foo-V1.0-java
dan menautkan ke file yang sesuai. Skrip yang secara otomatis melakukan ini untuk proyek yang penuh antarmuka dapat ditemukan di hardware/interfaces/update-makefiles.sh
. Jalur dalam contoh ini bersifat relatif; perangkat keras/antarmuka dapat menjadi direktori sementara di bawah pohon kode Anda untuk memungkinkan Anda mengembangkan HAL sebelum menerbitkannya.
Menjalankan layanan
HAL menyediakan antarmuka IFoo
, yang harus membuat panggilan balik asinkron ke kerangka kerja melalui antarmuka IFooCallback
. Antarmuka IFooCallback
tidak terdaftar namanya sebagai layanan yang dapat ditemukan; sebaliknya, IFoo
harus berisi metode seperti setFooCallback(IFooCallback x)
.
Untuk menyiapkan IFooCallback
dari paket android.hardware.foo
versi 1.0, tambahkan android.hardware.foo-V1.0-java
ke Android.mk
. Kode untuk 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 perangkat, ada kemungkinan bahwa pada perangkat tertentu layanan tersebut dapat memberikan kemampuan tambahan yang diterapkan dalam ekstensi antarmuka IBetterFoo
, sebagai berikut:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Memanggil kode yang mengetahui antarmuka yang diperluas dapat menggunakan metode castFrom()
Java untuk mentransmisikan antarmuka dasar ke antarmuka yang diperluas dengan aman:
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. }