Android 8.0'da Android işletim sistemi, cihazdan bağımsız Android platformu ile cihaza ve satıcıya özel kod arasında net arayüzler tanımlamak için yeniden tasarlandı. Android zaten hardware/libhardware
C başlıkları olarak tanımlanan HAL arayüzleri biçiminde bu tür birçok arayüzü tanımladı. HIDL, bu HAL arayüzlerini, Java'da (aşağıda açıklanmıştır) veya C++ 'da istemci ve sunucu tarafı HIDL arayüzleri olabilen kararlı, sürümlü arayüzlerle değiştirdi.
HIDL arayüzlerinin öncelikle yerel koddan kullanılması amaçlanmıştır ve sonuç olarak HIDL, C++'ta verimli kodun otomatik olarak oluşturulmasına odaklanır. Bununla birlikte, bazı Android alt sistemlerinde (Telefon gibi) Java HIDL arayüzleri bulunduğundan, HIDL arayüzlerinin doğrudan Java'dan kullanıma sunulması gerekir.
Bu bölümdeki sayfalarda HIDL arayüzleri için Java ön ucu açıklanmakta, hizmetlerin nasıl oluşturulacağı, kaydedileceği ve kullanılacağı ayrıntılarıyla anlatılmakta ve Java'da yazılan HAL'lerin ve HAL istemcilerinin HIDL RPC sistemiyle nasıl etkileşime girdiği açıklanmaktadır.
Müşteri olmak
Bu, default
hizmet adı olarak kaydedilen android.hardware.foo@1.0
paketindeki IFoo
arayüzüne ve second_impl
özel hizmet adına sahip ek bir hizmete yönelik bir istemci örneğidir.
Kitaplıklar ekleme
Kullanmak istiyorsanız ilgili HIDL saplama kitaplığına bağımlılıklar eklemeniz gerekir. Genellikle bu statik bir kütüphanedir:
// in Android.bp static_libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_STATIC_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Bu kitaplıklara zaten bağımlılıklar getirdiğinizi biliyorsanız, paylaşılan bağlantıyı da kullanabilirsiniz:
// in Android.bp libs: [ "android.hardware.foo-V1.0-java", ], // in Android.mk LOCAL_JAVA_LIBRARIES += android.hardware.foo-V1.0-java
Android 10'da kitaplık eklemeyle ilgili ek hususlar
Android 10 veya üstünü hedefleyen bir sistem veya satıcı uygulamanız varsa bu kitaplıkları statik olarak dahil edebilirsiniz. Ayrıca, sistem uygulamaları için mevcut uses-library
mekanizması kullanılarak kullanıma sunulan kararlı Java API'leri ile cihaza yüklenen özel JAR'lardaki (yalnızca) HIDL sınıflarını da kullanabilirsiniz. İkinci yaklaşım cihazda yerden tasarruf sağlar. Daha fazla ayrıntı için bkz. Java SDK Kitaplığını Uygulama . Daha eski uygulamalarda eski davranış korunur.
Android 10'dan itibaren bu kitaplıkların "sığ" sürümleri de mevcuttur. Bunlar söz konusu sınıfı içerir ancak bağımlı sınıfların hiçbirini içermez. Örneğin, android.hardware.foo-V1.0-java-shallow
, foo paketindeki sınıfları içerir, ancak tüm HIDL'lerin temel sınıfını içeren android.hidl.base-V1.0-java
içindeki sınıfları içermez. arayüzler. Tercih edilen arayüzün temel sınıflarının bağımlılık olarak zaten mevcut olduğu bir kitaplık oluşturuyorsanız aşağıdakileri kullanabilirsiniz:
// 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 tabanı ve yönetici kitaplıkları da artık uygulamalar için önyükleme sınıf yolunda mevcut değildir (daha önce, Android'in ilk temsilci sınıf yükleyicisi nedeniyle bazen gizli API olarak kullanılıyorlardı). Bunun yerine, jarjar
ile yeni bir ad alanına taşındılar ve bunları kullanan uygulamaların (mutlaka özel uygulamalar) kendi ayrı kopyalarına sahip olması gerekiyor. HIDL kullanan önyükleme sınıf yolundaki modüller, bu Java kitaplıklarının sığ değişkenlerini kullanmalı ve bu kitaplıkların önyükleme sınıf yolunda bulunan sürümünü kullanmak için Android.bp
jarjar_rules: ":framework-jarjar-rules"
eklemelidir.
Java kaynağınızı değiştirme
Bu hizmetin yalnızca bir sürümü ( @1.0
) olduğundan bu kod yalnızca bu sürümü alır. Hizmetin birden çok farklı sürümünün nasıl işleneceğini öğrenmek için arayüz uzantılarına bakın.
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(…);
Hizmet sunmak
Java'daki çerçeve kodunun, HAL'lerden eşzamansız geri aramaları almak için arayüzler sunması gerekebilir.
android.hardware.foo
paketinin 1.0 sürümündeki IFooCallback
arayüzü için, aşağıdaki adımları kullanarak arayüzünüzü Java'da uygulayabilirsiniz:
- Arayüzünüzü HIDL'de tanımlayın.
- Referans olarak
/tmp/android/hardware/foo/IFooCallback.java
dosyasını açın. - Java uygulamanız için yeni bir modül oluşturun.
-
android.hardware.foo.V1_0.IFooCallback.Stub
soyut sınıfını inceleyin, ardından onu genişletmek ve soyut yöntemleri uygulamak için yeni bir sınıf yazın.
Otomatik olarak oluşturulan dosyaları görüntüleme
Otomatik olarak oluşturulan dosyaları görüntülemek için şunu çalıştırın:
hidl-gen -o /tmp -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport android.hardware.foo@1.0
Bu komutlar /tmp/android/hardware/foo/1.0
dizinini oluşturur. hardware/interfaces/foo/1.0/IFooCallback.hal
dosyası için bu, Java arayüzünü, proxy kodunu ve saplamaları (her ikisi de proxy) kapsülleyen /tmp/android/hardware/foo/1.0/IFooCallback.java
dosyasını oluşturur. ve saplamalar arayüze uygundur).
-Lmakefile
derleme sırasında bu komutu çalıştıran kuralları oluşturur ve android.hardware.foo-V1.0-java
eklemenize ve uygun dosyalara bağlantı vermenize olanak tanır. Arayüzlerle dolu bir proje için bunu otomatik olarak yapan bir komut dosyası, hardware/interfaces/update-makefiles.sh
adresinde bulunabilir. Bu örnekteki yollar görecelidir; donanım/arayüzler, kod ağacınızın altında, yayınlamadan önce bir HAL geliştirmenize olanak tanıyan geçici bir dizin olabilir.
Bir hizmeti çalıştırma
HAL, IFooCallback
arayüzü üzerinden çerçeveye eşzamansız geri aramalar yapması gereken IFoo
arayüzünü sağlar. IFooCallback
arayüzü keşfedilebilir bir hizmet olarak isme göre kayıtlı değildir; bunun yerine IFoo
setFooCallback(IFooCallback x)
gibi bir yöntem içermesi gerekir.
IFooCallback
android.hardware.foo
paketinin 1.0 sürümünden ayarlamak için android.hardware.foo-V1.0-java
Android.mk
dosyasına ekleyin. Hizmeti çalıştıracak kod şudur:
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);
Arayüz uzantıları
Belirli bir hizmetin IFoo
arayüzünü tüm cihazlarda uyguladığını varsayarsak, belirli bir cihazda hizmetin IBetterFoo
arayüz uzantısında aşağıdaki gibi uygulanan ek yetenekleri sağlaması mümkündür:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Genişletilmiş arayüzün farkında olarak kod çağırmak, temel arayüzü genişletilmiş arayüze güvenli bir şekilde aktarmak için castFrom()
Java yöntemini kullanabilir:
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. }