Kararlı AIDL

Android 10'a kararlı Android arayüzü desteği eklendi Definition Language (AIDL), başvuru programını takip etmenin yeni bir yolu AIDL tarafından sağlanan arayüz (API) ve uygulama ikili arayüzü (ABI) kullanır. Kararlı AIDL, tam olarak AIDL gibi çalışır ancak derleme sistemi arayüz uyumluluğunu sağlayın ve yapabileceklerinizle ilgili kısıtlamalar vardır:

  • Arayüzler, derleme sisteminde aidl_interfaces ile tanımlanır.
  • Arayüzler yalnızca yapılandırılmış veriler içerebilir. tercih edilen türler, AIDL tanımlarına ve otomatik olarak sınırlandırılır ve kısıtlanmaz.
  • Arayüzler kararlı (geriye dönük uyumlu) olarak bildirilebilir. Bu API'leri izlenir ve sürümü, AIDL'nin yanındaki bir dosyada arayüzü.

Yapılandırılmış ve kararlı AIDL

Yapılandırılmış AIDL, tamamen AIDL'de tanımlanan türleri ifade eder. Örneğin, ayrıştırılabilir beyannamesi (özel parsel), yapılandırılmış AIDL değildir. Parseller ve bunların AIDL'de tanımlanmış alanlarına yapılandırılmış ayrıştırılabilir adı verilir.

Derleme sisteminin ve derleyicinin, kararlı AIDL ile yapılandırılmış AIDL kullanması için Parseller üzerinde yapılan değişikliklerin geriye dönük uyumlu olup olmadığını anlayabilir. Ancak tüm yapılandırılmış arayüzler kararlı değildir. İstikrarlı olmak için arayüzde yalnızca yapılandırılmış türler kullanılmalı ve arayüz, aşağıdakileri de kullanmalıdır: sürüm oluşturma özellikleri. Öte yandan, temel yapıyı kullanan bir arayüz kararlı sistemi kullanılır veya unstable:true ayarlanmışsa

AIDL arayüzü tanımlayın

aidl_interface tanımı şuna benzer:

aidl_interface {
    name: "my-aidl",
    srcs: ["srcs/aidl/**/*.aidl"],
    local_include_dir: "srcs/aidl",
    imports: ["other-aidl"],
    versions_with_info: [
        {
            version: "1",
            imports: ["other-aidl-V1"],
        },
        {
            version: "2",
            imports: ["other-aidl-V3"],
        }
    ],
    stability: "vintf",
    backend: {
        java: {
            enabled: true,
            platform_apis: true,
        },
        cpp: {
            enabled: true,
        },
        ndk: {
            enabled: true,
        },
        rust: {
            enabled: true,
        },
    },

}
  • name: Bir cihazı benzersiz şekilde tanımlayan AIDL arayüz modülünün adı AIDL arayüzü.
  • srcs: Arayüzü oluşturan AIDL kaynak dosyalarının listesi. Yol com.acme paketinde tanımlanan Foo AIDL türü için şu değerde olmalıdır: Burada <base_path> herhangi bir dizin olabilir <base_path>/com/acme/Foo.aidl Android.bp olduğu dizinle ilgilidir. Yukarıdaki örnekte <base_path>: srcs/aidl.
  • local_include_dir: Paket adının başladığı yol. Google yukarıda açıklanan <base_path> değerine karşılık gelir.
  • imports: Bu uygulamanın kullandığı aidl_interface modülün listesi. Projelerinizden biri AIDL arayüzleri, başka bir arayüzü veya ayrıştırıcıyı kullanır aidl_interface, adını buraya girin. Bu ad tek başına da olabilir. en son sürümü veya sürüm sonekini içeren ad (örneğin, -V1) sürüm oluşturabilirsiniz. Sürüm belirtme, Android 12'den beri destekleniyor
  • versions: Arayüzün önceki sürümleri olan Android 11 sürümünden itibaren, api_dir altında donduruldu, versions, aidl_api/name altında donduruldu. Bir arayüzün dondurulmuş sürümü yoksa, bu belirtilmemeli ve uyumluluk kontrolü yapılmayacaktır. Bu alan, Android için versions_with_info ile değiştirildi 13 ve üzeri.
  • versions_with_info: Her biri bir dondurulmuş sürüm ve diğer aidl_interface sürümünün içe aktarıldığı bir liste aidl_interface sürümünün içe aktardığı modüllerin sayısını artırır. Tanım AIDL arayüzünün V sürümünün (IFACE) bulunduğu sürüm aidl_api/IFACE/V Bu alan Android 13'te kullanıma sunuldu. ve doğrudan Android.bp içinde değiştirilmemesi gerekir. Bu, *-update-api veya *-freeze-api çağrılarak eklendi ya da güncellendi. Ayrıca, versions alan otomatik olarak versions_with_info hizmetine taşınır Kullanıcı *-update-api veya *-freeze-api yöntemini çağırdığında.
  • stability: Bu arayüzün kararlılık taahhüdüyle ilgili isteğe bağlı işarettir. Yalnızca "vintf" desteklenir. stability politikası ayarlanmazsa derleme yeni bir kod eklenmedikçe arayüzün geriye dönük uyumlu olup olmadığını unstable belirtilmişse. Ayarlanmadan ayarlama, tutarlılığı (yani her iki sistem de ne olursa olsun, örnek: system.img ve ilgili bölümlerdeki öğeler veya tüm tedarikçi firma (ör. vendor.img ve ilgili bölümlerdeki öğeler). Eğer stability, "vintf" olarak ayarlandı. Bu, kararlılık taahhüdüne karşılık gelir: arayüz, kullanıldığı sürece sabit tutulmalıdır.
  • gen_trace: İzlemeyi açmak veya kapatmak için kullanılan isteğe bağlı işaret. Başlamak için kalan süre: Android 14'te varsayılan olarak cpp ve true için java arka uç.
  • host_supported: true olarak ayarlandığında ana makine ortamı için oluşturulmuş kitaplıklar vardır.
  • unstable: Bu arayüzün şunları yapmadığını belirtmek için kullanılan isteğe bağlı işaret istikrarlı olması gerekir. Bu değer true olarak ayarlandığında, derleme sistemi arayüz için API dökümünü oluşturur veya güncellenmesini gerektirmez.
  • frozen: true olarak ayarlandığında arayüzün geçerli olacağı anlamına gelen isteğe bağlı işaret arayüzün önceki sürümünden bu yana herhangi bir değişiklik yok. Bu durumda, daha fazla derleme zamanı kontrolü var. Bu, false olarak ayarlandığında arayüzün açık olduğu anlamına gelir ve yeni değişiklikler içerdiğinden, foo-freeze-api çalıştırmak yeni sürüme geçer ve değeri otomatik olarak true şeklinde değiştirir. Tanıtıldığı oyun: Android 14.
  • backend.<type>.enabled: Bu işaretler, arka uçların her birini AIDL derleyicisi kod oluşturur. Dört arka uç, desteklenir: Java, C++, NDK ve Rust. Java, C++ ve NDK arka uçları etkinleştirilir varsayılan olarak. Bu üç arka uçtan herhangi birine ihtiyaç duyulmuyorsa arka uçlardan açıkça devre dışı bırakılır. Rust, Android'e kadar varsayılan olarak devre dışıdır 15.
  • backend.<type>.apex_available: Oluşturulan APEX adlarının listesi mevcut saplama kitaplığı da bulunuyor.
  • backend.[cpp|java].gen_log: işlemle ilgili bilgi toplamak için ek kod oluşturur.
  • backend.[cpp|java].vndk.enabled: Bu arayüzü sunmak için kullanılan isteğe bağlı işaret VNDK'nın bir parçası. false varsayılandır.
  • backend.[cpp|ndk].additional_shared_libraries: Tanıtıldığı oyun bu işaret, yerel kitaplıklar var. Bu işaret, ndk_header ve cpp_header ile kullanışlıdır.
  • backend.java.sdk_version: Sürümü belirtmek için kullanılan isteğe bağlı işaret kitaplığının temelini oluşturur. Varsayılan değer "system_current" backend.java.platform_apis durumunda ayarlanmamalıdır true.
  • backend.java.platform_apis: Oluşturulan kitaplıkların platform API'sine göre derlemesi gerektiğinde true bir önbellek sunar.

Sürümlerin ve etkinleştirilmiş arka uçların her kombinasyonu için bir saplama nasıl oluşturulur? Saplama kitaplığının belirli sürümüne referans vermek için belirli bir arka uç için Modül adlandırma kuralları bölümüne bakın.

AIDL dosyaları yazma

Kararlı AIDL'deki arayüzler geleneksel arayüzlere benzerdir; yalnızca yapılandırılmamış ayrıştırılabilir öğeleri kullanmalarına izin verilmez (çünkü bunlar kararlı değildir. Yapılandırılmış ve kararlı AIDL). Kararlı AIDL'deki temel fark tanımlanmıştır. Daha önce ileri beyan edilmiş; inç AIDL (ve dolayısıyla yapılandırılmış) AIDL, ayrıştırılabilir alanları ve değişkenleri açıkça tanımlanmıştır.

// in a file like 'some/package/Thing.aidl'
package some.package;

parcelable SubThing {
    String a = "foo";
    int b;
}

boolean, char için varsayılan bir sürüm desteklenir (ancak zorunlu değildir). float, double, byte, int, long ve String. Android'de 12. Kullanıcı tanımlı numaralandırmaların varsayılan değerleri de desteklenir. Bir varsayılan belirtilmediğinde, 0 benzeri veya boş bir değer kullanılır. Varsayılan değeri olmayan numaralandırmalar, sıfır numaralandırıcı yok.

Saplama kitaplıklarını kullanma

Modülünüze bağımlılık olarak stub kitaplıklarını ekledikten sonra bunları dosyalarınıza ekleyebilirsiniz. Burada, derleme sistemi (Android.mk, eski modül tanımları için de kullanılabilir):

cc_... {
    name: ...,
    shared_libs: ["my-module-name-cpp"],
    ...
}
# or
java_... {
    name: ...,
    // can also be shared_libs if your preference is to load a library and share
    // it among multiple users or if you only need access to constants
    static_libs: ["my-module-name-java"],
    ...
}
# or
rust_... {
    name: ...,
    rustlibs: ["my-module-name-rust"],
    ...
}

C++ ürününde örnek:

#include "some/package/IFoo.h"
#include "some/package/Thing.h"
...
    // use just like traditional AIDL

Java örneği:

import some.package.IFoo;
import some.package.Thing;
...
    // use just like traditional AIDL

Rust örneği:

use aidl_interface_name::aidl::some::package::{IFoo, Thing};
...
    // use just like traditional AIDL

Sürüm oluşturma arayüzleri

foo adında bir modül tanımlandığında derleme sisteminde de hedef oluşturulur API'sini kullanabilirsiniz. Oluşturulduğunda, foo-jpeg-api api_dir altına yeni bir API tanımı ekler veya Android sürümüne bağlı olarak aidl_api/name ve ekleme işlemi, her ikisi de sayfanızın yeni dondurulmuş sürümünü temsil eden bir .hash dosyası ekler. arayüzü. foo-dondurma-api, versions_with_info özelliğini de günceller. ifadesini kullanın.imports Özetlemek gerekirse versions_with_info öğesindeki imports, imports alanından kopyalandı. Ancak en son kararlı sürüm, şu cihaz için versions_with_info dilinde imports dilinde belirtilmiştir: içe aktarılmalıdır. versions_with_info özelliği belirtildikten sonra derleme sistemi çalıştırılır Dondurulmuş sürümler ve ayrıca ağacın üstü (ToT) arasındaki uyumluluk kontrolleri ve dondurulmuş en son sürüm.

Ayrıca, ToT sürümünün API tanımını da yönetmeniz gerekir. API, güncellendi, güncellemek için foo-update-api komutunu çalıştırın aidl_api/name/current ToT sürümünün API tanımını içerir.

Bir arayüzün kararlılığını korumak için, sahipler yeni özellikler ekleyebilirler:

  • Bir arayüzün sonundaki yöntemler (veya açıkça tanımlanmış yeni seri)
  • Bir ayrıştırılabilir öğenin sonuna eklenen öğeler (her biri için bir varsayılan öğesi ile aynı)
  • Sabit değerler
  • Android 11'de numaralandırıcılar
  • Android 12'de bir birleşimin sonuna kadar olan alanlar

Başka hiçbir işleme izin verilmez ve başka hiç kimse arayüzde değişiklik yapamaz (aksi takdirde, bir sahibin yaptığı değişikliklerle çakışma riskini alırlar).

Tüm arayüzlerin yayınlanmak üzere dondurulduğunu test etmek için şu çevresel değişkenler kümesi ayarlandı:

  • AIDL_FROZEN_REL=true m ...: Derleme işlemi için tüm kararlı AIDL arayüzleri gerekir: owner: alanı belirtilmeden dondurulabilir.
  • AIDL_FROZEN_OWNERS="aosp test" - Derleme için tüm kararlı AIDL arayüzleri gerekir "aosp" olarak belirtilen owner: alanı ile dondurulacak veya "test" yazın.

İthalatın kararlılığı

Bir arayüzün dondurulmuş sürümleri için içe aktarma sürümlerini güncellemek geriye dönük uyumluluğa sahiptir. Ancak, bunların güncellenmesi için arayüzün önceki bir sürümünü kullanan tüm sunucuları ve istemcileri güncelleyerek, Ayrıca bazı uygulamalar farklı türlerin karışımıyla karıştırılabilir. Genellikle yalnızca türler veya genel paketler için bu güvenlidir çünkü kodun IPC işlemlerinden bilinmeyen türleri işlemek için önceden yazılmış olmalıdır.

Android platform kodundaki android.hardware.graphics.common en büyük örneği verilmiştir.

Sürümlü arayüzleri kullanma

Arayüz yöntemleri

Çalışma zamanında, eski bir sunucuda yeni yöntemler çağırmaya çalışırken yeni istemciler arka uca bağlı olarak bir hata veya istisna oluşturur.

  • cpp arka ucu ::android::UNKNOWN_TRANSACTION alır.
  • ndk arka ucu STATUS_UNKNOWN_TRANSACTION alır.
  • java arka ucu, şu mesajı içeren android.os.RemoteException alıyor: API uygulanmadı.

Bunu ele alacak stratejiler için bkz. sorgulama sürümleri ve varsayılanları kullanarak ayarları değiştirebilirsiniz.

Parseller

Parsellere yeni alanlar eklendiğinde, eski istemciler ve sunucular bunları bırakır. Yeni istemciler ve sunucular eski paketleri aldığında yeni paket için varsayılan değerler alanları otomatik olarak doldurulur. Bu, varsayılan değerlerin tüm yeni alanlar için belirtilir.

Müşteriler, güncel bilgi sahibi olmadıkları sürece sunucuların yeni alanları kullanmasını sunucu, alanın tanımlanmış olduğu sürümü uyguluyor (bkz. sorgulama sürümleri) kaldırın.

Sıralamalar ve sabit değerler

Benzer şekilde, istemciler ve sunucular da tanınmayan iletileri reddetmeli veya yoksaymalıdır uygun şekilde sabit değerler ve numaralandırıcılar kullanın, çünkü sahip olacaksınız. Örneğin, bir sunucu bir bir numaralandırıcıdır. Sunucu, bir numara döndürür veya istemcinin bu uzantıda desteklenmediğini bilmesi için bazı ipuçları vereceğim.

Birlikler

Alıcı eskiyse ve yeni bir alanla bütünleştirme girişimi başarısız olursa olduğunu bilmiyor. Bu durumda, "Birleşik Krallık'ta hiçbir zaman yeni alana girin. Hata, tek yönlü işlem; aksi takdirde hata BAD_VALUE olur(C++ veya NDK için arka uç) veya IllegalArgumentException(Java arka ucu için). Hata: istemci, yeni alana sendikasyon ayarı eski bir alana yeni bir sunucudan birleştirmeyi alan eski bir istemci olduğunda ortaya çıkar.

Birden fazla sürümü yönetin

Android'deki bağlayıcı ad alanı, belirli bir aidl öğesinin yalnızca 1 sürümünü içerebilir oluşturulan aidl türlerinin birden fazla karaktere sahip olduğu durumlardan kaçınmak için arayüze tanımlar. C++, yalnızca bir tanım gerektiren tek tanımlama kuralına sahiptir anlamına gelir.

Bir modül farklı bir modüle bağlı olduğunda Android derlemesi hata veriyor aynı aidl_interface kitaplığının sürümleri. Modül, kullandığınız e-posta, bağımlılıklarıyla doğrudan veya dolaylı olarak bu kitaplıkları ve bildirmeyi konuştuk. Bu hatalar, başarısız olan modülden başlayıp aidl_interface kitaplığının çakışan sürümleri. Tüm bağımlılıkların aynı (genellikle en yeni) sürümü içerecek şekilde güncellenmesi gerekir emin olmanız gerekir.

Arayüz kitaplığı birçok farklı modül tarafından kullanılıyorsa, ve şunun herhangi bir grup için cc_defaults, java_defaults ve rust_defaults oluşturmak üzere kitaplık ve işlemlerde aynı sürümü kullanması gerekir. Bir projeyi arayüzün yeni sürümünde bu varsayılan ayarlar güncellenebilir ve tüm modüllerin farklı sürümler kullanmadıklarından emin olmak için birlikte güncellenirler. görebilirsiniz.

cc_defaults {
  name: "my.aidl.my-process-group-ndk-shared",
  shared_libs: ["my.aidl-V3-ndk"],
  ...
}

cc_library {
  name: "foo",
  defaults: ["my.aidl.my-process-group-ndk-shared"],
  ...
}

cc_binary {
  name: "bar",
  defaults: ["my.aidl.my-process-group-ndk-shared"],
  ...
}

aidl_interface modül diğer aidl_interface modülü içe aktardığında bu işlem şunları oluşturur: belirli sürümlerin birlikte kullanılmasını gerektiren başka bağımlılıklar da var. Bu aidl_interface söz konusu olduğunda bu durumu yönetmek zor olabilir. kullanılan birden fazla aidl_interface modülüne aktarılmış modüller üretildiğini öğrendik.

aidl_interfaces_defaults, tanımını yapmak için kullanılabilir güncellenebilecek bir aidl_interface için bağımlılıkların en son sürümleri ve içe aktarmak isteyen aidl_interface modülün tamamı tarafından kullanılır. deniyor.

aidl_interface_defaults {
  name: "android.popular.common-latest-defaults",
  imports: ["android.popular.common-V3"],
  ...
}

aidl_interface {
  name: "android.foo",
  defaults: ["my.aidl.latest-ndk-shared"],
  ...
}

aidl_interface {
  name: "android.bar",
  defaults: ["my.aidl.latest-ndk-shared"],
  ...
}

Bayrağa dayalı geliştirme

Geliştirme aşamasındaki (dondurulmuş) arayüzler, geriye dönük uyumlu oldukları garanti edilmez.

AIDL, bu dondurulmuş arayüz kitaplıkları için sırasıyla çalışma zamanı yedeğini destekler en son dondurulmuş sürüme göre yazılacak ve yine de kullanılacak sürüm cihazlarında. İstemcilerin geriye dönük uyumlu davranışı, ve yedek ile birlikte, uygulamaların da kendi içinde tespit etmiş olursunuz. Görüntüleyin Farklı sürümlü arayüzler kullanın.

AIDL derleme işareti

Bu davranışı kontrol eden işaret RELEASE_AIDL_USE_UNFROZEN build/release/build_flags.bzl içinde tanımlanmıştır. true, cihazın dondurulmuş versiyonunu ifade eder arayüz çalışma zamanında kullanılır ve false, Dondurulmuş sürümlerin tümü, son dondurulmuş sürümleri gibi davranır. Aşağıdakiler için işareti true olarak geçersiz kılabilirsiniz: yerel geliştirme, ancak yayınlanmadan önce false sürümüne geri döndürülmesi gerekir. Normal şartlarda Geliştirme, işareti true olarak ayarlanmış bir yapılandırmayla gerçekleştirilir.

Uyumluluk matrisi ve manifest'ler

Tedarikçi firma arayüzü nesneleri (VINTF nesneleri) hangi sürümlerin beklendiğini ve her iki tarafta da hangi sürümlerin çok önemlidir.

Cuttlefish dışındaki çoğu cihaz en son uyumluluk matrisini hedefler Yalnızca arayüzler dondurulduktan sonra AIDL'de fark yoktur. RELEASE_AIDL_USE_UNFROZEN tabanlı kitaplıklar.

Matrisler

İş ortağına ait arayüzler, cihaza veya ürüne özel arayüzlere eklendiğinde cihazın geliştirme sırasında hedeflediği uyumluluk matrislerini belirlemenize yardımcı olur. Bir arayüzün yeni, dondurulmamış sürümü bir uyumluluk matrisine eklendiğinde, önceki dondurulmuş sürümlerin kullanımda kalması gerekir RELEASE_AIDL_USE_UNFROZEN=false Bu sorunu çözmek için farklı farklı RELEASE_AIDL_USE_UNFROZEN için uyumluluk matrisi dosyaları yapılandırmalarına veya tek bir uyumluluk matrisi dosyasında her iki sürüme izin vermelerine yapılandırmada kullanılır.

Örneğin, dondurulmuş sürüm 4'ü eklerken <version>3-4</version> değerini kullanın.

Sürüm 4 dondurulduğunda sürüm 3'ü uyumluluk matrisinden kaldırabilirsiniz Çünkü dondurulmuş sürüm 4, RELEASE_AIDL_USE_UNFROZEN şu durumda kullanılır: false.

Manifestler

Android 15'te libvintf sürümünde yapılan bir değişiklik manifest dosyalarını derleme zamanında şu değere göre değiştirin: RELEASE_AIDL_USE_UNFROZEN.

Manifest'ler ve manifest parçaları, arayüzün hangi sürümünün kullanılacağını yardımcı olur. Bir arayüzün en son dondurulmuş sürümünü kullanırken manifest, bu yeni sürümü yansıtacak şekilde güncellenmelidir. Zaman RELEASE_AIDL_USE_UNFROZEN=false manifest girişleri şuna göre ayarlanır: Oluşturulan AIDL kitaplığındaki değişikliği yansıtmak için libvintf. Sürüm dondurulmuş sürüm olan N sürümünden dondurulmuş son sürüm N - 1. Dolayısıyla, kullanıcıların birden fazla her biri için manifest veya manifest parçaları.

HAL istemcisiyle ilgili değişiklikler

HAL istemci kodu, önceki desteklenen her dondurulmuş kodla geriye dönük uyumlu olmalıdır sürümünü değil. RELEASE_AIDL_USE_UNFROZEN false olduğunda hizmetler her zaman görünür Örneğin, dondurulmuş son sürüm veya önceki sürümler (örneğin, dondurulmuş yeni sürümü çağırma yöntemleri UNKNOWN_TRANSACTION değerini döndürür veya yeni parcelable alanları varsayılan değerlere) gidin. Android çerçeve istemcilerinin geriye dönük olması gerekir Bunlar, önceki ek sürümlerle uyumludur, ancak bu, tedarikçi firma müşterileri ve iş ortağına ait arayüz müşterileri.

HAL uygulaması değişiklikleri

Bayrak tabanlı geliştirme ile HAL gelişimindeki en büyük fark önceki sürümle geriye dönük uyumluluğa sahip olması koşuluyla, RELEASE_AIDL_USE_UNFROZEN false olduğunda çalışacak şekilde dondurulmuş sürüm. Uygulamalarda ve cihaz kodunda geriye dönük uyumluluğu göz önünde bulundurmak, bir egzersizdir. Sürümü kullanılan öğeleri kullanma" bölümüne göz atın. bilgi edinin.

Geriye dönük uyumlulukla ilgili dikkat edilmesi gereken noktalar genellikle çerçeve kodu ve tedarikçi kodu için de geçerlidir, ancak ve artık üretken yapay zekanın gücünden yararlandığınızdan aynı kaynak kodunu kullanan iki sürüm (mevcut, dondurulmuş sürümü) gösterilir.

Örnek: Bir arayüzün dondurulmuş üç sürümü vardır. Arayüzdeki yeni bir yöntem olabilir. Hem istemci hem de hizmet yeni sürüm 4'ü kullanacak şekilde güncellenir kitaplığını açar. V4 kitaplığı, cihazın dondurulmamış sürümüne çalışırken son dondurulmuş sürüm 3 gibi davranır. RELEASE_AIDL_USE_UNFROZEN, false değerine ayarlanır ve yeni yöntemin kullanımını engeller.

Arayüz dondurulduğunda tüm RELEASE_AIDL_USE_UNFROZEN değerleri, ve geriye dönük uyumluluğu işleyen kod kaldırılabilir.

Geri çağırma yöntemlerinde çağrılarken, şu durumlarda konuyu titizlikle ele almanız gerekir: UNKNOWN_TRANSACTION döndürüldü. Müşteriler, farklı yöntemler ya da geri çağırmanın sürümleri kullanıldığından, istemcinin en yeni sürümü gönderdiğini ve yeni yöntemlerin bu. Bu, AIDL istemcilerinin kararlılığını korumasına benzer Sürümü farklı kullanma" bölümünde açıklandığı üzere sunucularla uyumluluk bilgi edinin.

// Get the callback along with the version of the callback
ScopedAStatus RegisterMyCallback(const std::shared_ptr<IMyCallback>& cb) override {
    mMyCallback = cb;
    // Get the version of the callback for later when we call methods on it
    auto status = mMyCallback->getInterfaceVersion(&mMyCallbackVersion);
    return status;
}

// Example of using the callback later
void NotifyCallbackLater() {
  // From the latest frozen version (V2)
  mMyCallback->foo();
  // Call this method from the unfrozen V3 only if the callback is at least V3
  if (mMyCallbackVersion >= 3) {
    mMyCallback->bar();
  }
}

Mevcut türlerdeki yeni alanlar (parcelable, enum, union) RELEASE_AIDL_USE_UNFROZEN olduğunda mevcut değildir veya varsayılan değerlerini içerir. false ve bir hizmetin göndermeye çalıştığı yeni alanların değerleri atlanıyor çok önemli bir parçasıdır.

Bu dondurulmuş sürüme eklenen yeni türler gönderilemez üzerinden alınabilir.

Uygulama, aşağıdaki durumlarda hiçbir zaman istemcilerden yeni yöntemler RELEASE_AIDL_USE_UNFROZEN false.

Yeni numaralandırıcıları yalnızca kullanıma sunuldukları sürümle birlikte kullanmaya dikkat edin. değil.

Normalde uzaktan kumandanın hangi sürümü olduğunu öğrenmek için foo->getInterfaceVersion() kullanırsınız. gösterir. Ancak bayrağa dayalı sürüm oluşturma desteği ile bu nedenle her birinin kendi sürümünü kullanmak yeni arayüze geçelim. Bunu, nesne (ör. this->getInterfaceVersion() veya diğer) my_ver için yöntemler. Bkz. Uzaktan kumandanın arayüz sürümünü sorgulama nesne konulu videomuzu izleyin.

Yeni VINTF kararlı arayüzleri

Yeni bir AIDL arayüz paketi eklendiğinde son dondurulmuş sürüm yoktur, bu nedenle RELEASE_AIDL_USE_UNFROZEN olduğunda geri alınacak bir davranış yoktur. false. Bu arayüzleri kullanmayın. RELEASE_AIDL_USE_UNFROZEN şu olduğunda: false, Hizmet Yöneticisi, hizmetin arayüzü kaydetmesine izin vermiyor müşteriler de bulamaz.

Şu değere göre hizmetleri koşullu olarak ekleyebilirsiniz: Cihaz oluşturma dosyasında RELEASE_AIDL_USE_UNFROZEN işareti:

ifeq ($(RELEASE_AIDL_USE_UNFROZEN),true)
PRODUCT_PACKAGES += \
    android.hardware.health.storage-service
endif

Hizmet daha büyük bir işlemin parçasıysa ve cihaza eklenemiyorsa şartlı olarak, hizmetin IServiceManager::isDeclared() Beyan edilmiş olmasına rağmen kaydedilemediyse işlemi iptal edebilir. Beyan edilmemişse kaydedilemez.

Bir geliştirme aracı olarak mürekkep balığı

VINTF dondurulduktan sonra her yıl çerçeve uyumluluğunu düzenliyoruz. matrisi (FCM) target-level ve Mürekkep balığının PRODUCT_SHIPPING_API_LEVEL kadarı Böylece gelecek yıl piyasaya sürülecek cihazları yansıtır. Belirli aralıklarla Bazı ayrıntıların bulunduğundan emin olmak için target-level ve PRODUCT_SHIPPING_API_LEVEL test edilmiş ve gelecek yılın yeni gerekliliklerini karşılayan kullanabilirsiniz.

RELEASE_AIDL_USE_UNFROZEN true olduğunda Mürekkep balığı Android sürümlerinin geliştirilmesinde kullanılır. Gelecek yılın Android'ini hedefliyor sürümünün FCM düzeyini ve PRODUCT_SHIPPING_API_LEVEL düzeyini karşılaması gerekir. sonraki sürümün Tedarikçi Yazılım Gereksinimlerini (VSR) gerektirir.

RELEASE_AIDL_USE_UNFROZEN false olduğunda, Mürekkep balığı öncekine sahip olur Sürüm cihazını göstermek için target-level ve PRODUCT_SHIPPING_API_LEVEL. Android 14 ve önceki sürümlerde bu ayrım FCM değişikliğine etki etmeyen farklı Git dallarıyla başarıyla gerçekleştirilir target-level, kargo API'si düzeyi veya sonrakini hedefleyen başka bir kod kullanabilirsiniz.

Modül adlandırma kuralları

Android 11'de her bir sürüm kombinasyonu ve arka uçlar etkinleştirildiğinde saplama kitaplığı modülü otomatik olarak oluşturulur. Referans bağlantı için belirli bir saplama kitaplığı modülüne değil, aidl_interface modülünün adıdır, ancak ifacename-version-backend, burada

  • ifacename: aidl_interface modülünün adı
  • version şunlardan biridir:
    • Dondurulmuş sürümler için Vversion-number
    • Şu tarih için Vlatest-frozen-version-number + 1: ağaç ucu (henüz dondurulmuş) versiyonu
  • backend şunlardan biridir:
    • Java arka ucu için java,
    • C++ arka ucu için cpp,
    • NDK arka ucu için ndk veya ndk_platform. Birincisi uygulamalar içindir, İkincisi ise Android 13'e kadar platform kullanımı içindir. İçinde Android 13 ve sonraki sürümler, yalnızca ndk kullanın.
    • Rust arka ucu için rust.

foo adında bir modül olduğunu ve en son sürümünün 2 olduğunu varsayalım. ve hem NDK'yı hem de C++'yı destekliyor. Bu durumda AIDL şu modülleri oluşturur:

  • Sürüm 1'e göre
    • foo-V1-(java|cpp|ndk|ndk_platform|rust)
  • Sürüm 2'yi (en son kararlı sürüm) temel alır
    • foo-V2-(java|cpp|ndk|ndk_platform|rust)
  • ToT sürümüne göre
    • foo-V3-(java|cpp|ndk|ndk_platform|rust)

Android 11 ile karşılaştırıldığında:

  • foo-backend (en son kararlı sürümü ifade eder). sürüm foo-V2-backend olur
  • foo-unstable-backend, (Hizmet Şartları'na atıfta bulunuluyor) sürüm foo-V3-backend olur

Çıkış dosyalarının adları her zaman modül adlarıyla aynıdır.

  • 1. sürüme göre: foo-V1-(cpp|ndk|ndk_platform|rust).so
  • 2. sürüme göre: foo-V2-(cpp|ndk|ndk_platform|rust).so
  • ToT sürümüne göre: foo-V3-(cpp|ndk|ndk_platform|rust).so

AIDL derleyicisinin bir unstable sürüm modülü oluşturmadığını unutmayın. veya sürümü değiştirilmemiş bir modüldür. Android 12'den itibaren kararlı AIDL arayüzünün her zaman sürümünü içerir.

Yeni meta arayüz yöntemleri

Android 10, AIDL'nin kararlı çalışmasıdır.

Uzak nesnenin arayüz sürümünü sorgulayın

İstemciler, uzak nesnenin çalıştırıldığı arayüzün sürümünü ve karmasını ve döndürülen değerleri arayüzün değerleriyle uygulamak ve karşılaştırmak teklif vermelidir.

cpp arka ucuyla örnek:

sp<IFoo> foo = ... // the remote object
int32_t my_ver = IFoo::VERSION;
int32_t remote_ver = foo->getInterfaceVersion();
if (remote_ver < my_ver) {
  // the remote side is using an older interface
}

std::string my_hash = IFoo::HASH;
std::string remote_hash = foo->getInterfaceHash();

ndk (ve ndk_platform) arka ucuyla örnek:

IFoo* foo = ... // the remote object
int32_t my_ver = IFoo::version;
int32_t remote_ver = 0;
if (foo->getInterfaceVersion(&remote_ver).isOk() && remote_ver < my_ver) {
  // the remote side is using an older interface
}

std::string my_hash = IFoo::hash;
std::string remote_hash;
foo->getInterfaceHash(&remote_hash);

java arka ucuyla örnek:

IFoo foo = ... // the remote object
int myVer = IFoo.VERSION;
int remoteVer = foo.getInterfaceVersion();
if (remoteVer < myVer) {
  // the remote side is using an older interface
}

String myHash = IFoo.HASH;
String remoteHash = foo.getInterfaceHash();

Java dili için uzak tarafın getInterfaceVersion() ve getInterfaceHash() aşağıdaki gibidir (kaçınılması için IFoo yerine super kullanılır) kolayca uygulayabilirsiniz. @SuppressWarnings("static") ek açıklaması javac yapılandırmasına bağlı olarak uyarıları devre dışı bırakmak için gereklidir):

class MyFoo extends IFoo.Stub {
    @Override
    public final int getInterfaceVersion() { return super.VERSION; }

    @Override
    public final String getInterfaceHash() { return super.HASH; }
}

Bunun nedeni, oluşturulan sınıfların (IFoo, IFoo.Stub vb.) paylaşılmasıdır. arasında bağlantı kurar (örneğin, sınıflar sınıf yolu). Sınıflar paylaşıldığında, sunucu sınıfların en yeni sürümü, eski bir sürümle oluşturulmuş yeni bir sürüm oluşturun. Bu meta arayüz, paylaşılan sınıfını her zaman en yeni sürümü döndürür. Ancak metodu uygulayarak yukarıda belirtildiği gibi, arayüzün sürüm numarası sunucunun koduna gömülüdür. (IFoo.VERSION, referans verildiğinde satır içi olan bir static final int olduğu için) ve böylece yöntem, sunucunun birlikte derlendiği sürümü tam olarak döndürebilir.

Eski arayüzlerle ilgilenin

İstemciler, AIDL'nin yeni sürümüyle güncellenmiş olabilir arayüzü ancak sunucu eski AIDL arayüzünü kullanıyor. Böyle durumlarda eski bir arayüzde bir yöntemin çağrılması UNKNOWN_TRANSACTION sonucunu döndürür.

Kararlı AIDL sayesinde istemciler daha fazla kontrole sahip olur. İstemci tarafında, başlangıçtaki AIDL arayüzünün varsayılan uygulaması. Varsayılan yöntem uygulama, yalnızca yöntem uzaktan kumandada uygulanmadığında çağrılır (çünkü arayüzün eski bir sürümüyle oluşturulduğu için). Başlangıç varsayılan olarak ayarlandığından, paylaşılan olmadığından bağlamlar.

Android 13 ve sonraki sürümlerde C++ için örnek:

class MyDefault : public IFooDefault {
  Status anAddedMethod(...) {
   // do something default
  }
};

// once per an interface in a process
IFoo::setDefaultImpl(::android::sp<MyDefault>::make());

foo->anAddedMethod(...); // MyDefault::anAddedMethod() will be called if the
                         // remote side is not implementing it

Java örneği:

IFoo.Stub.setDefaultImpl(new IFoo.Default() {
    @Override
    public xxx anAddedMethod(...)  throws RemoteException {
        // do something default
    }
}); // once per an interface in a process

foo.anAddedMethod(...);

AIDL'deki tüm yöntemlerin varsayılan uygulamasını sağlamanız gerekmez arayüzü. Uzak tarafta uygulanması garanti edilen yöntemler (çünkü uzaktan kumandanın, içerdiği yöntemler AIDL arayüzü açıklaması) varsayılan impl ayarında geçersiz kılınması gerekmez sınıfını kullanır.

Mevcut AIDL'yi yapılandırılmış veya kararlı AIDL'ye dönüştürün

Mevcut bir AIDL arayüzünüz ve onu kullanan kodunuz varsa şunu kullanın: arayüzü kararlı bir AIDL arayüzüne dönüştürme adımlarına göz atın.

  1. Arayüzünüzün tüm bağımlılıklarını belirleyin. Her paket için paketin kararlı AIDL'de tanımlanıp tanımlanmadığını belirleyin. Eğer tanımlanmadıysa paketin dönüştürülmesi gerekir.

  2. Arayüzünüzdeki tüm parseller ( arayüz dosyalarının kendileri değişmeden kalabilir). Bu işlemi şu tarihe kadar yapın: (yapılarını doğrudan AIDL dosyalarında ifade etme) Yönetim sınıfları bu yeni türleri kullanacak şekilde yeniden yazılır. Bu işlem, aidl_interface paketi (aşağıda).

  3. Şunları içeren bir aidl_interface paketi (yukarıda açıklandığı gibi) oluşturun: ve ihtiyacınız olan diğer bilgileri gözden geçirebilirsiniz. Sabitlenmesi (sadece yapılandırılmış değil) için de sürüm oluşturulması gerekir. Daha fazla bilgi için Sürüm oluşturma arayüzleri konusuna bakın.