HIDL Java

Android 8.0'da Android işletim sistemi net arayüzler tanımlayacak şekilde yeniden tasarlandı Cihazdan bağımsız Android platformu ile cihaza ve satıcıya özgü girin. Android bu tür arayüzlerin birçoğunu HAL biçiminde tanımlamıştır. arayüzleri, hardware/libhardware içinde C başlıkları olarak tanımlanır. İDL Bu HAL arayüzlerini sabit, sürümü oluşturulmuş arayüzlerle değiştirdi. Java'da (aşağıda açıklanmıştır) ya da istemci ve sunucu tarafında HIDL olmalıdır. C++'daki arayüzler.

HIDL arayüzlerinin birincil olarak yerel koddan kullanılması ve aynı zamanda bir HIDL, C++'ta otomatik olarak verimli kod oluşturmaya odaklanmıştır. Ancak, HIDL arayüzleri ayrıca bazı Android cihazlarda olduğu gibi, doğrudan Java'dan kullanıma sunulmalıdır. alt sistemlerinin (Telephony gibi) Java HIDL arayüzleri vardır.

Bu bölümdeki sayfalarda HIDL arayüzleri için Java ön ucu açıklanmaktadır. hizmetlerin nasıl oluşturulacağını, kaydettirileceğini ve kullanılacağını ayrıntılandırma ve HAL'ler ile HAL'lerin nasıl kullanılacağını açıklama istemciler, HIDL RPC sistemiyle etkileşime girer.

İstemci örneği

Bu, paketindeki IFoo arayüzüne ait bir istemci örneğidir Hizmet adı olarak kayıtlı android.hardware.foo@1.0 default ve özel hizmet adıyla ek bir hizmet second_impl.

Kitaplık ekleyin

Aşağıdaki durumlarda ilgili HIDL saplama kitaplığına bağımlılık eklemeniz gerekir: onu kullanmak istiyorsunuz. Bu genellikle 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ık çektiğinizi biliyorsanız paylaşılan bağlantıyı da kullanabilir:

// 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 diğer noktalar

Android 10 veya sonraki bir sürümü hedefleyen bir sistem ya da satıcı uygulamanız varsa: bu kitaplıkları statik olarak ekleyebilirsiniz. Yalnızca (yalnızca) HIDL sınıflarını da kullanabilirsiniz kullanıma sunulmuş kararlı Java API'leriyle cihaza yüklenmiş özel JAR'lardan (sistem uygulamaları için mevcut uses-library mekanizmasını kullanarak). İlgili içeriği oluşturmak için kullanılan cihazda yer tasarrufu yapmasını sağlar. Daha fazla bilgi için Java SDK Kitaplığı'nı uygulama başlıklı makaleyi inceleyin. Örneğin, uygulamalarda eski davranış korunur.

Android 10'dan itibaren, "sığ" bu kitaplıkların sürümleri mevcuttur. Bunlar söz konusu sınıfı içerir ancak herhangi bir sınıf içermez belirler. Örneğin, android.hardware.foo-V1.0-java-shallow, foo'daki sınıfları içerir paketine dahil edilir ancak android.hidl.base-V1.0-java; HIDL arayüzleri. Zaten tercih edilen arayüzün temel sınıflarını bağımlı olarak kullanmak istiyorsanız, şunu 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ı da artık başlatma sırasında kullanılamaz uygulamalar için sınıf yolu (önceden, gizlilik nedeniyle Android'in yetki verilmiş öncelikli sınıf yükleyicisi). Bunun yerine, yeni bir jarjar ile ad alanı ve bunları kullanan uygulamalar (zorunlu olarak uygulamalar) ayrı kopyaları olmalıdır. Başlatma sınıf yolundaki modüller: HIDL, bu Java kitaplıklarının yüzeysel varyantlarını kullanmalıdır ve jarjar_rules: ":framework-jarjar-rules" - kendi Bu kitaplıkların mevcut sürümünü kullanmak için Android.bp inceleyebilirsiniz.

Java kaynağınızı değiştirme

Bu hizmetin yalnızca bir sürümü (@1.0) olduğu için bu kod yalnızca ilgili sürümü getirir. Görüntüleyin arayüz uzantıları sürümünün nasıl ele alınacağına ilişkin bilgiler içerir.

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ğlama

Java'da çerçeve kodunun, eşzamansız veri almak için arayüzleri sunması gerekebilir geri arama yapıyor.

Sürüm 1.0'daki IFooCallback arayüzü için android.hardware.foo paketinde, arayüzünüzü Şu adımları uygulayarak Java:

  1. HIDL'de arayüzünüzü tanımlayın.
  2. /tmp/android/hardware/foo/IFooCallback.java uygulamasını şu şekilde aç: bir referans noktası olarak kabul edilir.
  3. Java uygulamanız için yeni bir modül oluşturun.
  4. Soyut sınıfı inceleme android.hardware.foo.V1_0.IFooCallback.Stub, ardından yeni bir sınıf yazın soyut yöntemleri uygulamaktır.

Otomatik olarak oluşturulan dosyaları görüntüle

Otomatik olarak oluşturulan dosyaları görüntülemek için şu komutu ç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 Dosya için hardware/interfaces/foo/1.0/IFooCallback.hal kullanıyorsanız içeren /tmp/android/hardware/foo/1.0/IFooCallback.java dosyası Java arayüzü, proxy kodu ve koçları (hem proxy hem de saplamalar arayüze göre ayarlanır).

-Lmakefile, derleme sırasında bu komutu çalıştıran kuralları oluşturur zaman ayırabilir ve her bir android.hardware.foo-V1.0-java ve uygun dosyalar olabilir. Dolu bir proje için bunu otomatik olarak yapan bir arayüzleri hardware/interfaces/update-makefiles.sh adresinde bulabilirsiniz. Bu örnekteki yollar görelidir; donanım/arayüz geçici olabilir dizine ekleme işlemleri ekleyebilirsiniz. Bu sayede, kod ağacınızın altında üzerine konuşacağım.

Hizmet çalıştırma

HAL, eşzamansız olması gereken IFoo arayüzünü sağlar IFooCallback arayüzü üzerinden çerçeveye yapılan geri çağırmaları ifade eder. İlgili içeriği oluşturmak için kullanılan IFooCallback arayüzü, adla bulunabilir olarak kayıtlı değil hizmet; bunun yerine, IFoo şöyle bir yöntem içermelidir: setFooCallback(IFooCallback x).

IFooCallback kurulumunu android.hardware.foo paketi, ekle android.hardware.foo-V1.0-java - Android.mk. Kod üç farklı yol var:

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 uygulamalarda IFoo arayüzünü uyguladığını bir hizmet, belirli bir cihazda veya belirli bir cihazda arayüz uzantısında uygulanan ek özellikler IBetterFoo gibi:

interface IFoo {
   ...
};

interface IBetterFoo extends IFoo {
   ...
};

Genişletilmiş arayüzden haberdar çağrı kodu, castFrom() Temel arayüzü güvenli bir şekilde genişletilmiş arayüz:

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.
}