AIDL'deki ek açıklamalar

AIDL, ek açıklamalı öğe hakkında AIDL derleyicisine ek bilgi veren ek açıklamaları destekler. Bu durum, oluşturulan saplama kodunu da etkiler.

Söz dizimi Java'ya benzer:

@AnnotationName(argument1=value, argument2=value) AidlEntity

Burada AnnotationName, açıklamanın adı, AidlEntity ise interface Foo, void method() veya int arg gibi bir AIDL öğesidir. Bir ek açıklama, kendisini takip eden varlığa eklenir.

Bazı ek açıklamalar, önceki örnekte gösterildiği gibi parantez içinde bağımsız değişkenler içerebilir. Bağımsız değişkeni olmayan notlarda parantez kullanılması gerekmez. Örneğin:

@AnnotationName AidlEntity

Bu notlar, Java notlarına benzese de aynı değildir. Tüm ek açıklamalar önceden tanımlanmıştır ve nereye eklenebilecekleri konusunda kısıtlamalar vardır. Bazı ek açıklamalar yalnızca belirli bir arka ucu etkiler ve diğer arka uçlarda işlem yapmaz.

Önceden tanımlanmış AIDL ek açıklamalarının listesi:

Ek AçıklamalarEklendiği Android sürümü
nullable7
utf8InCpp7
VintfStability11
UnsupportedAppUsage10
Hide11
Backing11
NdkOnlyStableParcelable14
JavaOnlyStableParcelable11
JavaDerive12
JavaPassthrough12
FixedSize12
Descriptor12

null değer alabilir

nullable, açıklama eklenen öğenin değerinin boş olabileceğini belirtir.

Bu ek açıklamayı yalnızca yöntem dönüş türlerine, yöntem parametrelerine ve paketlenebilir alanlara ekleyebilirsiniz:

interface IFoo {
    // method return types
    @nullable Data method();

    // method parameters
    void method2(in @nullable Data d);
}

parcelable Data {
    // parcelable fields
    @nullable Data d;
}

Açıklamalar temel türlere eklenemez. Aşağıdaki bir hatadır:

void method(in @nullable int a); // int is a primitive type

Bu ek açıklama, Java arka ucu için işlem yapmaz. Java'da tüm ilkel olmayan türler referansla iletilir. Bu, null olabilir.

CPP arka ucunda, @nullable T Android 11 veya daha eski sürümlerde std::unique_ptr<T>'ye, Android 12 veya daha yeni sürümlerde ise std::optional<T>'ye eşlenir.

NDK arka ucunda @nullable T, std::optional<T> ile eşlenir.

Rust arka ucunda @nullable T, Option<T> ile eşlenir.

T[] veya List<T> gibi liste benzeri bir tür için L, @nullable L, std::optional<std::vector<std::optional<T>>> ile eşlenir (veya Android 11 ya da daha eski sürümlerdeki PBM arka ucu için std::unique_ptr<std::vector<std::unique_ptr<T>>>).

Bu eşlemenin bir istisnası vardır. T, IBinder veya bir AIDL arayüzü olduğunda @nullable, Rust hariç tüm arka uçlar için işlem yapmaz. Başka bir deyişle, hem @nullable IBinder hem de IBinder, android::sp<IBinder> ile eşit şekilde eşlenir. android::sp<IBinder>, güçlü bir işaretçi olduğu için zaten boş değer atanabilir (CPP okumaları boş değer atanabilirliği zorunlu kılmaya devam eder ancak tür yine de android::sp<IBinder>'dir). Rust'ta bu türler yalnızca @nullable ile açıklama eklenirse nullable olur. Açıklama eklenirse Option<T> ile eşlenir.

Android 13'ten itibaren, yinelemeli türleri modellemek için @nullable(heap=true) kullanılabilir. @nullable(heap=true), yöntem parametreleri veya dönüş türleriyle kullanılamaz. Bu ifadeyle açıklama eklendiğinde alan, CPP ve NDK arka uçlarında yığın olarak ayrılmış bir referansla std::unique_ptr<T> eşlenir. @nullable(heap=true), Java arka ucunda işlem yapmaz.

utf8InCpp

utf8InCpp, CPP arka ucu için String öğesinin UTF8 biçiminde temsil edildiğini belirtir. Adından da anlaşılacağı gibi, ek açıklama diğer arka uçlar için işlem yapmaz. Özellikle String, Java arka ucunda her zaman UTF16, NDK arka ucunda ise UTF8'dir.

Bu ek açıklama, dönüş değerleri, parametreler, sabit bildirimleri ve paketlenebilir alanlar dahil olmak üzere String türünün kullanılabildiği her yere eklenebilir.

CPP arka ucu için AIDL'deki @utf8InCpp String, std::string ile eşlenir. Burada, ek açıklama içermeyen String, UTF16'nın kullanıldığı android::String16 ile eşlenir.

VintfStability

VintfStability, kullanıcı tanımlı bir türün (arayüz, paketlenebilir ve enum) sistem ve satıcı alanlarında kullanılabileceğini belirtir. Sistem-satıcı birlikte çalışabilirliği hakkında daha fazla bilgi için HAL'ler için AIDL başlıklı makaleyi inceleyin.

Ek açıklama, türün imzasını değiştirmez ancak ayarlandığında türün örneği kararlı olarak işaretlenir. Böylece, tedarikçi ve sistem süreçleri arasında taşınabilir.

Açıklama yalnızca kullanıcı tanımlı tür bildirimlerine eklenebilir. Bu işlem, burada gösterildiği gibi yapılır:

@VintfStability
interface IFoo {
    ....
}

@VintfStability
parcelable Data {
    ....
}

@VintfStability
enum Type {
    ....
}

Bir tür VintfStability ile açıklama eklenmişse türde referans verilen diğer türler de bu şekilde açıklama eklenmelidir. Aşağıdaki örnekte, hem Data hem de IBar, VintfStability ile açıklama eklenmelidir:

@VintfStability
interface IFoo {
    void doSomething(in IBar b); // references IBar
    void doAnother(in Data d); // references Data
}

@VintfStability // required
interface IBar {...}

@VintfStability // required
parcelable Data {...}

Ayrıca, VintfStability ile ek açıklama eklenmiş türleri tanımlayan AIDL dosyaları yalnızca aidl_interface Soong modül türü kullanılarak oluşturulabilir ve stability özelliği vintf olarak ayarlanır:

aidl_interface {
    name: "my_interface",
    srcs: [...],
    stability: "vintf",
}

UnsupportedAppUsage

UnsupportedAppUsage ek açıklaması, ek açıklama eklenen AIDL türünün eski uygulamalar tarafından erişilebilen SDK dışı arayüzün bir parçası olduğunu gösterir. Gizli API'ler hakkında daha fazla bilgi için SDK olmayan arayüzlerdeki kısıtlamalar başlıklı makaleyi inceleyin.

UnsupportedAppUsage ek açıklaması, oluşturulan kodun davranışını etkilemez. Ek açıklama, yalnızca aynı ada sahip Java ek açıklamasıyla oluşturulan Java sınıfına ek açıklama ekler:

// in AIDL
@UnsupportedAppUsage
interface IFoo {...}

// in Java
@android.compat.annotation.UnsupportedAppUsage
public interface IFoo {...}

Bu, Java olmayan arka uçlar için işlem yapmayan bir işlemdir.

Destekleme notu

Backing notu, AIDL enum türünün depolama türünü belirtir:

@Backing(type="int")
enum Color { RED, BLUE, }

CPP arka ucunda bu, int32_t türünde bir C++ enum sınıfı oluşturur:

enum class Color : int32_t {
    RED = 0,
    BLUE = 1,
}

Ek açıklama çıkarılırsa type değerinin byte olduğu varsayılır. Bu değer, CPP arka ucu için int8_t ile eşlenir.

type bağımsız değişkeni yalnızca aşağıdaki tam sayı türlerine ayarlanabilir:

  • byte (8 bit genişliğinde)
  • int (32 bit genişliğinde)
  • long (64 bit genişliğinde)

NdkOnlyStableParcelable

NdkOnlyStableParcelable, diğer sabit AIDL türlerinden referans verilebilmesi için paketlenebilir bir bildirimi (tanım değil) sabit olarak işaretler. Bu, JavaOnlyStableParcelable'ye benzer ancak NdkOnlyStableParcelable, Java yerine NDK arka ucu için paketlenebilir bir bildirimi kararlı olarak işaretler.

Bu paketlenebilir öğeyi kullanmak için:

  • ndk_header değerini belirtmeniz gerekir.
  • Paketlenebilirliği belirten bir NDK kitaplığınız olmalı ve kitaplık, kitaplığa derlenmelidir. Örneğin, bir cc_* modülündeki temel derleme sisteminde static_libs veya shared_libs kullanın. aidl_interface için Android.bp'deki additional_shared_libraries bölümünde kitaplığı ekleyin.

JavaOnlyStableParcelable

JavaOnlyStableParcelable, diğer sabit AIDL türlerinden referans verilebilmesi için paketlenebilir bir bildirimi (tanım değil) sabit olarak işaretler.

Kararlı AIDL, kullanıcı tanımlı tüm türlerin kararlı olmasını gerektirir. Parcelable'lar için kararlı olmak, alanlarının AIDL kaynak dosyasında açıkça açıklanmasını gerektirir:

parcelable Data { // Data is a structured parcelable.
    int x;
    int y;
}

parcelable AnotherData { // AnotherData is also a structured parcelable
    Data d; // OK, because Data is a structured parcelable
}

Parcelable yapılandırılmamışsa (veya yalnızca bildirilmişse) referans verilemez:

parcelable Data; // Data is NOT a structured parcelable

parcelable AnotherData {
    Data d; // Error
}

JavaOnlyStableParcelable, referans verdiğiniz parcelable Android SDK'nın bir parçası olarak güvenli bir şekilde kullanılabildiğinde kontrolü geçersiz kılmanıza olanak tanır:

@JavaOnlyStableParcelable
parcelable Data;

parcelable AnotherData {
    Data d; // OK
}

JavaDerive

JavaDerive Java arka ucunda, paketlenebilir türler için yöntemleri otomatik olarak oluşturur:

@JavaDerive(equals = true, toString = true)
parcelable Data {
  int number;
  String str;
}

Açıklama, neyin oluşturulacağını kontrol etmek için ek parametreler gerektirir. Desteklenen parametreler şunlardır:

  • equals=true, equals ve hashCode yöntemlerini oluşturur.
  • toString=true, türün adını ve alanlarını yazdıran toString yöntemini oluşturur. Örneğin, Data{number: 42, str: foo}.

JavaDefault (desteği sonlandırıldı)

Android 13'te eklenen JavaDefault, varsayılan uygulama sürüm oluşturma desteğinin (setDefaultImpl için) oluşturulup oluşturulmayacağını kontrol eder. Alan tasarrufu için bu destek artık varsayılan olarak oluşturulmaz.

JavaPassthrough

JavaPassthrough, oluşturulan Java API'nin rastgele bir Java ek açıklamasıyla açıklanmasına olanak tanır.

AIDL'deki bu ek açıklamalar:

@JavaPassthrough(annotation="@android.annotation.Alice")
@JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")

oluşturulan Java kodunda aşağıdaki gibi olur:

@android.annotation.Alice
@com.android.Alice(arg=com.android.Alice.Value.A)

annotation parametresinin değeri doğrudan yayınlanır. AIDL derleyicisi, parametrenin değerini incelemez. Java düzeyinde söz dizimi hatası varsa bu hata AIDL derleyicisi tarafından değil, Java derleyicisi tarafından yakalanır.

Bu ek açıklama herhangi bir AIDL öğesine eklenebilir. Bu ek açıklama, Java dışı arka uçlar için işlem yapmaz.

RustDerive

RustDerive, oluşturulan Rust türleri için özellikleri otomatik olarak uygular.

Açıklama, neyin oluşturulacağını kontrol etmek için ek parametreler gerektirir. Desteklenen parametreler şunlardır:

  • Copy=true
  • Clone=true
  • Ord=true
  • PartialOrd=true
  • Eq=true
  • PartialEq=true
  • Hash=true

Bu özelliklerin açıklamaları için Rust belgelerine bakın.

FixedSize

FixedSize, yapılandırılmış bir paketlenebilir öğeyi sabit boyutlu olarak işaretler. İşaretlendikten sonra, paketlenebilir öğeye yeni alanlar ekleyemezsiniz. Paketlenebilir öğenin tüm alanları, ilkel türler, numaralandırmalar, sabit boyutlu diziler ve FixedSize ile işaretlenmiş diğer paketlenebilir öğeler dahil olmak üzere sabit boyutlu türler olmalıdır.

Tanımlayıcı

Descriptor bir arayüzün arayüz tanımlayıcısını zorunlu olarak belirtir:

package android.foo;

@Descriptor(value="android.bar.IWorld")
interface IHello {...}

Bu arayüzün tanımlayıcısı android.bar.IWorld'dır. Descriptor ek açıklaması eksikse tanımlayıcı android.foo.IHello olur.

Bu, daha önce yayınlanmış bir arayüzü yeniden adlandırmak için kullanışlıdır. Yeniden adlandırılan arayüzün tanımlayıcısını, yeniden adlandırma işleminden önceki arayüzün tanımlayıcısıyla aynı yapmak, iki arayüzün birbiriyle iletişim kurmasını sağlar.

@hide in comments

AIDL derleyicisi, yorumlardaki @hide karakterini tanır ve metalava'nın alması için Java çıkışına iletir. Bu yorum, Android derleme sisteminin AIDL API'lerinin SDK API'leri olmadığını tanımasını sağlar.

Yorumlarda @deprecated

AIDL derleyicisi, yorumlardaki @deprecated işaretini artık kullanılmaması gereken bir AIDL öğesini tanımlayan etiket olarak tanır:

interface IFoo {
  /** @deprecated use bar() instead */
  void foo();
  void bar();
}

Her arka uç, arka uca özgü bir ek açıklama veya özellik ile kullanımdan kaldırılan öğeleri işaretler. Böylece, istemci kodu kullanımdan kaldırılan öğelere başvurursa uyarılır. Örneğin, @Deprecated ek açıklaması ve @deprecated etiketi, Java ile oluşturulan koda eklenir.