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 C başlıklarını olarak tanımlanan HAL arayüzleri şeklinde birçok tür arayüzler tanımlanmış hardware/libhardware
. HIDL ya Java (aşağıda tarif edilmektedir) olması veya bir istemci ve sunucu tarafındaki HIDL arayüzleri olabilen kararlı, sürüm arabirimleri, bu HAL arayüzleri ikame C ++ .
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 bir arayüz için bir istemci örneğidir IFoo
paket içinde android.hardware.foo@1.0
hizmet adı olarak kayıtlı default
ve özel hizmet adı ile ek bir hizmet second_impl
.
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 istikrarlı Java API'leri ile cihazda yüklü özel kavanozları dan (yalnızca) HIDL sınıflarını kullanabilirsiniz mevcut kullanarak sunulan uses-library
sistemi uygulamaları için bir mekanizma. İkinci yaklaşım, cihazda yerden tasarruf sağlar. Daha fazla ayrıntı için bkz Uygulama Java SDK Kütüphane . 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 sınıfları içermez android.hidl.base-V1.0-java
tüm HIDL temel sınıf içerir, 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, yeni bir ad götürüldüler jarjar
ve bu (muhakkak priv uygulamalar) kullanmak uygulamalarının kendi ayrı kopyalarını olması gerekir. Sığ bu Java kütüphanelerin varyantları kullanmalıdır ve eklenecek HIDL kullanarak önyükleme üzerinde sınıf Modülleri jarjar_rules: ":framework-jarjar-rules"
kendi için Android.bp
önyükleme sınıf yolunda var olan bu kütüphanelerin sürümünü kullanmak için.
Java kaynağınızı değiştirme
(Yalnızca bir sürümü var @1.0
Bu hizmetin) bu kod Geri alma işlemlerinde bu yüzden sadece bu sürümü. Bkz arayüz uzantıları hizmetin birden fazla farklı versiyonlarını nasıl işleneceğini için.
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.
For IFooCallback
1.0 sürümünde arayüzünde android.hardware.foo
paketinde, aşağıdaki adımları kullanarak Java sizin arabirimini uygulayabilirsiniz:
- HIDL'de arayüzünüzü tanımlayın.
- Açık
/tmp/android/hardware/foo/IFooCallback.java
bir referans olarak. - Java uygulamanız için yeni bir modül oluşturun.
- Soyut sınıf inceleyin
android.hardware.foo.V1_0.IFooCallback.Stub
, sonra uzatmak ve soyut yöntemler 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 dizini oluşturmak /tmp/android/hardware/foo/1.0
. Dosya için hardware/interfaces/foo/1.0/IFooCallback.hal
, bu dosya oluşturur /tmp/android/hardware/foo/1.0/IFooCallback.java
Java arayüzü kapsüller, proxy kodu ve koçanları (hem vekil ve taslaklar arayüze uygundur).
-Lmakefile
yapı anda bu komutu çalıştırmak ve eklemek için izin kuralları üretir android.hardware.foo-V1.0-java
uygun dosyalara karşı ve bağlantı. Otomatik arayüzleri dolu bir proje için bunu yapar bir senaryo bulunabilir 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 sağlar IFoo
üzerinde çerçeveye asenkron geri aramalar yapmak gerekir arayüzü, IFooCallback
arayüzüne. IFooCallback
arayüzü keşfedilebilir hizmet olarak adıyla kayıtlı değil; bunun yerine, IFoo
gibi bir yöntem içermelidir setFooCallback(IFooCallback x)
.
Kurmak için IFooCallback
1.0 sürümünden android.hardware.foo
paketi eklemek android.hardware.foo-V1.0-java
için Android.mk
. 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ı
Verilen hizmet uygulayan varsayarsak IFoo
tüm cihazlarda arayüzü, belirli bir cihazda hizmet arayüzü uzantısında uygulanan ek yetenekleri sağlayabilir mümkündür IBetterFoo
aşağıdaki gibi:
interface IFoo { ... }; interface IBetterFoo extends IFoo { ... };
Kullanabilirsiniz uzatılmış arabiriminin farkında kod çağırma castFrom()
güvenle uzatılmış arayüzüne taban arayüzünü döküm için Java yöntemi:
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. }