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, hardware/libhardware
C başlıkları olarak tanımlanan HAL arabirimleri biçiminde bu tür birçok arabirimi zaten tanımladı. HIDL, bu HAL arabirimlerini, Java'da olabilen (aşağıda açıklanmıştır) veya C++' da istemci ve sunucu tarafı HIDL arabirimleri olabilen kararlı, sürümlü arabirimlerle değiştirdi.
HIDL arabirimlerinin öncelikli olarak yerel koddan kullanılması amaçlanmıştır ve sonuç olarak HIDL, C++'da verimli kodun otomatik olarak oluşturulmasına odaklanır. Ancak, bazı Android alt sistemlerinde (Telephony gibi) Java HIDL arabirimleri bulunduğundan, HIDL arabirimlerinin doğrudan Java'dan da kullanılabilir olması gerekir.
Bu bölümdeki sayfalar, HIDL arabirimleri için Java ön ucunu açıklar, hizmetlerin nasıl oluşturulacağını, kaydedileceğini ve kullanılacağını ayrıntılı olarak açıklar ve Java'da yazılan HAL'lerin ve HAL istemcilerinin HIDL RPC sistemi ile nasıl etkileşime girdiğini açıklar.
müşteri olmak
Bu, hizmet adı default
olarak kayıtlı android.hardware.foo@1.0
paketindeki IFoo
arabirimi için bir istemci örneği ve second_impl
özel hizmet adıyla ek bir hizmettir.
Kitaplık ekleme
Kullanmak istiyorsanız, ilgili HIDL saplama kitaplığına bağımlılıklar eklemeniz gerekir. Genellikle, bu statik bir kitaplıktır:
// 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 çektiğ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 (yalnızca) sistem uygulamaları için mevcut uses-library
mekanizması kullanılarak sağlanan kararlı Java API'leri ile cihaza yüklenen özel JAR'lardan HIDL sınıflarını da kullanabilirsiniz. İkinci yaklaşım, cihazda yerden tasarruf sağlar. Daha fazla ayrıntı için Java SDK Kitaplığını Uygulama konusuna bakın. Daha eski uygulamalar için eski davranış korunur.
Android 10'dan başlayarak, 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 arabirimin bağımlılık olarak kullanılabilen temel sınıflarına sahip 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 temel ve yönetici kitaplıkları artık uygulamalar için önyükleme sınıf yolunda mevcut değildir (önceden, Android'in temsilci birinci 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ı olmalıdır. HIDL kullanan önyükleme sınıf yolundaki modüller, bu Java kitaplıklarının sığ türevlerini 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
) vardır, bu nedenle bu kod yalnızca o sürümü alır. Hizmetin birden çok farklı sürümünün nasıl ele alınacağını öğrenmek için arabirim 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 sağlamak
Java'daki çerçeve kodunun, HAL'lerden eşzamansız geri aramalar almak için arabirimler sunması gerekebilir.
android.hardware.foo
paketinin 1.0 sürümündeki IFooCallback
arabirimi için, aşağıdaki adımları kullanarak arabiriminizi Java'da uygulayabilirsiniz:
- HIDL'de arayüzünüzü tanımlayın.
- Referans olarak
/tmp/android/hardware/foo/IFooCallback.java
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 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 arabirimini, proxy kodunu ve taslakları (her ikisi de proxy) içine alan /tmp/android/hardware/foo/1.0/IFooCallback.java
dosyasını oluşturur. ve taslaklar arayüze uygundur).
-Lmakefile
, bu komutu derleme zamanında çalıştıran ve android.hardware.foo-V1.0-java
dahil etmenize ve uygun dosyalara bağlantı vermenize izin veren kuralları oluşturur. Arayüzlerle dolu bir proje için bunu otomatik olarak yapan bir komut dosyası, hardware/interfaces/update-makefiles.sh
. Bu örnekteki yollar görecelidir; donanım/arayüzler, yayınlamadan önce bir HAL geliştirmenizi sağlamak için kod ağacınızın altındaki geçici bir dizin olabilir.
Bir hizmeti çalıştırma
HAL, IFoo
arabirimi üzerinden çerçeveye zaman uyumsuz geri aramalar yapması gereken IFooCallback
arabirimini sağlar. IFooCallback
arabirimi, keşfedilebilir bir hizmet olarak adıyla kayıtlı değildir; bunun yerine, IFoo
setFooCallback(IFooCallback x)
gibi bir yöntem içermelidir.
android.hardware.foo
paketinin 1.0 sürümünden IFooCallback
kurmak için, Android.mk
dosyasına android.hardware.foo-V1.0-java
ekleyin. Hizmeti çalıştırmak için 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 tüm aygıtlarda IFoo
arabirimini uyguladığını varsayarsak, hizmetin belirli bir aygıtta IBetterFoo
arabirim uzantısında uygulanan ek yetenekleri aşağıdaki gibi sağlaması mümkündür:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Genişletilmiş arabirimden haberdar olan çağrı kodu, temel arabirimi genişletilmiş arabirime güvenli bir şekilde yayınlamak 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. }