HIDL Java

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:

  1. HIDL'de arayüzünüzü tanımlayın.
  2. Açık /tmp/android/hardware/foo/IFooCallback.java bir referans olarak.
  3. Java uygulamanız için yeni bir modül oluşturun.
  4. 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.
}