Android 10, kararlı Android Arayüz Tanımlama Dili (AIDL) desteği ekler. Bu, AIDL arayüzleri tarafından sağlanan uygulama programlama arayüzünü (API) ve uygulama ikili arayüzünü (ABI) takip etmenin yeni bir yoludur. Kararlı AIDL, AIDL ile aynı şekilde çalışır ancak derleme sistemi arayüz uyumluluğunu izler ve yapabileceğiniz işlemler konusunda 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ürleri temsil eden Parcelables, AIDL tanımlarına göre otomatik olarak oluşturulur ve otomatik olarak marshallenir ve unmarshallenir.
- Arayüzler kararlı (geriye dönük uyumlu) olarak tanımlanabilir. Bu durumda, API'leri AIDL arayüzünün yanındaki bir dosyada izlenir ve sürümleri belirlenir.
Yapılandırılmış ve kararlı AIDL
Yapılandırılmış AIDL, yalnızca AIDL'de tanımlanan türleri ifade eder. Örneğin, ayrıştırılabilir beyannamesi (özel parsel), yapılandırılmış AIDL değildir. AIDL'de tanımlanan alanları olan Parcelables'lara yapılandırılmış Parcelables denir.
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. Bir arayüzün kararlı olması için yalnızca yapılandırılmış türlerin yanı sıra aşağıdaki sürüm oluşturma özelliklerini de kullanması gerekir. Buna karşılık, bir arayüz oluşturmak için temel derleme sistemi kullanılırsa veya unstable:true
ayarlanırsa arayüz kararlı olmaz.
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. Yolcom.acme
paketinde tanımlananFoo
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>
değeri: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. AIDL arayüzlerinizden biri başka biraidl_interface
'den bir arayüz veya paketlenebilir öğe kullanıyorsa adını buraya yazın. 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 özelliği Android 12'den beri desteklenmektedir.versions
: Arayüzünapi_dir
altında dondurulmuş önceki sürümleri. Android 11'den itibarenversions
,aidl_api/name
altında dondurulur. Bir arayüzün dondurulmuş sürümü yoksa bu belirtilmemelidir ve uyumluluk kontrolleri yapılmaz. Bu alan, Android içinversions_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 adresinde bulunur:aidl_api/IFACE/V
Bu alan Android 13'te kullanıma sunuldu. ve doğrudanAndroid.bp
içinde değiştirilmemesi gerekir. Alan,*-update-api
veya*-freeze-api
çağrılarak eklenir ya da güncellenir. Ayrıca, kullanıcı*-update-api
veya*-freeze-api
'i çağrdığındaversions
alanları otomatik olarakversions_with_info
alanına taşınır.stability
: Bu arayüzün kararlılık taahhüdüyle ilgili isteğe bağlı işarettir. Bu 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. Ayarlanmamış olma durumu, bu derleme bağlamında kararlılığa sahip bir arayüze karşılık gelir (yani tüm sistem öğeleri (ör.system.img
ve ilgili bölümlerdeki öğeler) veya tüm tedarikçi öğeleri (ör.vendor.img
ve ilgili bölümlerdeki öğeler)). Eğerstability
,"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 etkinleştirmek veya devre dışı bırakmak için isteğe bağlı işaret. Android 14'ten itibarencpp
vejava
arka uçları için varsayılan değertrue
'tir.host_supported
:true
olarak ayarlandığında oluşturulan kitaplıkların ana makine ortamına sunulmasını sağlayan isteğe bağlı işaret.unstable
: Bu arayüzün şunları yapmadığını belirtmek için kullanılan isteğe bağlı işaret istikrarlı olması gerekir. Bu değertrue
olarak ayarlandığında derleme sistemi, arayüz için API dökümünü oluşturmaz ve güncellenmesini gerektirmez.frozen
:true
olarak ayarlandığında arayüzün önceki sürümünden bu yana herhangi bir değişiklik olmadığını belirten isteğe bağlı işaret. Bu sayede daha fazla derleme zamanı kontrolü yapılabilir.false
olarak ayarlandığında arayüzün geliştirme aşamasında olduğu ve yeni değişiklikler içerdiği anlamına gelir. Bu nedenle,foo-freeze-api
çalıştırıldığında yeni bir sürüm oluşturulur ve değer otomatik olaraktrue
olarak değiştirilir. Tanıtıldığı oyun: Android 14.backend.<type>.enabled
: Bu işaretler, arka uçları açma/kapatma işlemini 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
: İşlemle ilgili bilgi toplamak için ek kod oluşturulup oluşturulmayacağını kontrol eden isteğe bağlı işaret.backend.[cpp|java].vndk.enabled
: Bu arayüzü VNDK'nın bir parçası haline getirmek için isteğe bağlı işaret. Varsayılan değerfalse
'tir.backend.[cpp|ndk].additional_shared_libraries
: Tanıtıldığı oyun Bu işaret, yerel kitaplıklar var. Bu işaret,ndk_header
vecpp_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
true
olduğunda bu ayarlanmamalıdır.backend.java.platform_apis
: Oluşturulan kitaplıkların SDK yerine platform API'sine göre derlenmesi gerektiğindetrue
olarak ayarlanması gereken isteğe bağlı işaret.
Sürümlerin ve etkinleştirilmiş arka uçların her kombinasyonu için bir saplama nasıl oluşturulur? Belirli bir arka uç için stub kitaplığının belirli bir sürümüne nasıl referans verileceği hakkında bilgi edinmek için Modül adlandırma kuralları başlıklı makaleyi inceleyin.
AIDL dosyaları yazma
Kararlı AIDL'deki arayüzler, geleneksel arayüzlere benzer. Bununla birlikte, yapılandırılmamış paketlenebilirlerin kullanılmasına izin verilmez (çünkü bunlar kararlı değildir. Yapılandırılmış ve kararlı AIDL bölümüne bakın). Kararlı AIDL'deki birincil fark, paketlenebilirlerin nasıl tanımlandığıdır. Daha önce ileri beyan edilmiş; bir listesini oluştur: 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
, float
, double
, byte
, int
, long
ve String
için varsayılan değer desteklenir (ancak zorunlu değildir). Android'de
12. Kullanıcı tanımlı numaralandırmaların varsayılan değerleri de
desteklenir. Varsayılan değer belirtilmediğinde 0'a benzer veya boş bir değer kullanılır.
Varsayılan değeri olmayan numaralandırmalar,
sıfır numaralandırıcı yok.
Kütüphane taslağı kullanma
Modülünüze bağımlı olarak stub kitaplıklarını ekledikten sonra bunları dosyalarınıza dahil edebilirsiniz. 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'ta örnek:
use aidl_interface_name::aidl::some::package::{IFoo, Thing};
...
// use just like traditional AIDL
Arayüzlerin sürümlerini oluşturma
foo adlı bir modül tanımladığınızda, derleme sisteminde modülün API'sini yönetmek için kullanabileceğiniz bir hedef de oluşturulur. Derlendiğinde foo-freeze-api, Android sürümüne bağlı olarak api_dir
veya aidl_api/name
altında yeni bir API tanımı ve her ikisi de arayüzün yeni dondurulmuş sürümünü temsil eden bir .hash
dosyası ekler. foo-freeze-api, versions_with_info
mülkünü ek sürümü ve sürüm için imports
'i yansıtacak şekilde de günceller. Özetlemek gerekirse
versions_with_info
öğesindeki imports
, imports
alanından kopyalandı. Ancak açık bir sürümü olmayan içe aktarma işlemi için versions_with_info
içindeki imports
bölümünde en son kararlı sürüm belirtilmiştir.
versions_with_info
mülkü belirtildikten sonra derleme sistemi, dondurulmuş sürümler arasında ve ayrıca ağaç üst kısmı (ToT) ile en son dondurulmuş sürüm arasında uyumluluk kontrolleri yapar.
Ayrıca, ToT sürümünün API tanımını yönetmeniz gerekir. Bir API güncellendiğinde, ToT sürümünün API tanımını içeren aidl_api/name/current
dosyasını güncellemek için foo-update-api komutunu çalıştırın.
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 serilere sahip yöntemler)
- Paketlenebilir bir öğenin sonundaki öğeler (her öğe için varsayılan bir değer eklenmesini gerektirir)
- Sabit değerler
- Android 11'de dize dizenler
- Android 12'de bir birleşimin sonuna kadar olan alanlar
Başka işlemlere izin verilmez ve başka hiç kimse arayüzde değişiklik yapamaz (aksi takdirde, sahibin yaptığı değişikliklerle çakışabilir).
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 belirtilenowner:
alanı ile dondurulacak veya "test" yazın.
İçe aktarma işlemlerinin 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, arayüzün önceki bir sürümünü kullanan tüm sunucuların ve istemcilerin güncellenmesini gerektirir. Ayrıca bazı uygulamalar, türlerin farklı sürümlerini karıştırırken karışıklık yaşayabilir. 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 ucuSTATUS_UNKNOWN_TRANSACTION
alır.java
arka ucu, şu mesajı içerenandroid.os.RemoteException
alıyor: API uygulanmadı.
Bu sorunu gidermek için sürümleri sorgulama ve varsayılanları kullanma başlıklı makalelere bakın.
Parseller
Parsellere yeni alanlar eklendiğinde, eski istemciler ve sunucular bunları bırakır. Yeni istemciler ve sunucular eski paketlenebilir öğeleri aldığında yeni alanlar için varsayılan değerler otomatik olarak doldurulur. Bu, paketlenebilir bir öğedeki tüm yeni alanlar için varsayılan değerlerin belirtilmesi gerektiği anlamına gelir.
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, gelecekte daha fazlası eklenebileceği için tanınmayan sabit değerleri ve dize dizinlerini uygun şekilde reddetmeli veya yok saymalıdır. Örneğin, bir sunucu, bilmediği bir dizine ekleme işlevi aldığında işlemi iptal etmemelidir. 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 alan hakkında bilgi sahibi değilse yeni bir alan içeren bir birleştirme göndermeye çalışmak başarısız olur. Uygulama, yeni alanla birleşme işlemini hiçbir zaman görmez. Tek yönlü bir işlemse hata yoksayılır. Aksi takdirde hata BAD_VALUE
(C++ veya NDK arka uç için) ya da IllegalArgumentException
(Java arka uç için) olur. Müşteri yeni alana ayarlanmış bir birleştirme gönderiyorsa veya eski bir müşteri yeni bir sunucudan birleştirme aldığında bu hata alınır.
Birden fazla sürümü yönetme
Android'deki bağlayıcı ad alanı, belirli bir aidl
öğesinin yalnızca 1 sürümüne sahip olabilir
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. Arayüzün yeni bir sürümü kullanıma sunulduğunda bu varsayılan değerler güncellenebilir ve bunları kullanan tüm modüller birlikte güncellenerek arayüzün farklı sürümlerini kullanmamaları sağlanır.
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
, bir aidl_interface
için bağımlılıkların en son sürümlerinin tek bir yerde güncellenebilen ve bu ortak arayüzü içe aktarmak isteyen tüm aidl_interface
modülleri tarafından kullanılabilen tek bir tanımını tutmak için kullanılabilir.
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 (dondurulmamış) arayüzlerin geriye dönük uyumlu olması garanti edilmediğinden, bu arayüzler yayın cihazlarında kullanılamaz.
AIDL, kodun dondurulmamış en son sürüme göre yazılabilmesi ve yine de yayın cihazlarında kullanılabilmesi için bu dondurulmamış arayüz kitaplıkları için çalışma zamanında yedekleme desteği sunar. İstemcilerin geriye dönük uyumlu davranışı mevcut davranışa benzer. Yedekleme ile birlikte, uygulamaların bu davranışları da uygulaması gerekir. Sürümlü arayüzleri kullanma başlıklı makaleyi inceleyin.
AIDL derleme işareti
Bu davranışı kontrol eden işaret, build/release/build_flags.bzl
içinde RELEASE_AIDL_USE_UNFROZEN
tanımlanır. true
, arayüzün dondurulmamış sürümünün çalışma zamanında kullanıldığı anlamına gelir. false
ise dondurulmamış sürümlerin kitaplıklarının 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. Geliştirme genellikle işareti true
olarak ayarlanmış bir yapılandırmayla yapılır.
Uyumluluk matrisi ve manifest'ler
Tedarikçi arayüzü nesneleri (VINTF nesneleri), tedarikçi arayüzünün her iki tarafında hangi sürümlerin beklendiğini ve hangi sürümlerin sağlandığını tanımlar.
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. Bu nedenle, bir arayüzün dondurulmamış yeni bir sürümü uyumluluk matrisine eklendiğinde, önceki dondurulmuş sürümlerin RELEASE_AIDL_USE_UNFROZEN=false
için kalmasının 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.
4. sürüm dondurulduğunda RELEASE_AIDL_USE_UNFROZEN
false
olduğunda dondurulmuş 4. sürüm kullanılacağından 3. sürümü uyumluluk matrisinden kaldırabilirsiniz.
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. RELEASE_AIDL_USE_UNFROZEN=false
olduğunda, manifest girişleri, oluşturulan AIDL kitaplığındaki değişikliği yansıtacak şekilde libvintf
tarafından ayarlanır. 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, desteklenen önceki her dondurulmuş sürümle geriye dönük uyumlu olmalıdır. 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 önceki sürümlerle geriye dönük uyumlu olması gerekir ancak bu, tedarikçi istemcileri ve iş ortağına ait arayüz istemcileri için yeni bir ayrıntıdır.
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ümlendirilmiş arayüzleri kullanma başlıklı makaleyi inceleyin.
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 4. sürüm kitaplığı kullanacak şekilde güncellenir. V4 kitaplığı, arayüzün dondurulmamış bir sürümünü temel aldığından, RELEASE_AIDL_USE_UNFROZEN
false
olduğunda son dondurulmuş sürüm (3. sürüm) gibi davranır ve yeni yöntemin kullanılmasını engeller.
Arayüz dondurulduğunda RELEASE_AIDL_USE_UNFROZEN
değerinin tümünde dondurulmuş sürüm kullanılır ve geriye dönük uyumluluğu yöneten 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ü. İstemciler, sürüm yapılandırmasına bağlı olarak geri çağırma işlevinin iki farklı sürümünü uygulayabilir. Bu nedenle, istemcinin en yeni sürümü gönderdiğini varsayamazsınız ve yeni yöntemler bunu döndürebilir. 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.
Uzak arayüzün hangi sürümü kullandığını görmek için normalde foo->getInterfaceVersion()
'ü kullanırsınız. Ancak işarete dayalı sürüm desteğiyle iki farklı sürüm uyguladığınız için mevcut arayüzün sürümünü almak isteyebilirsiniz. Bunu, geçerli nesnenin arayüz sürümünü (ör. this->getInterfaceVersion()
) veya my_ver
için diğer yöntemleri alarak yapabilirsiniz. Daha fazla bilgi için Uzak nesnenin arayüz sürümünü sorgulama başlıklı makaleyi inceleyin.
Yeni VINTF kararlı arayüzleri
Yeni bir AIDL arayüz paketi eklendiğinde son dondurulmuş sürüm olmadığından RELEASE_AIDL_USE_UNFROZEN
false
olduğunda geri dönülecek bir davranış yoktur. 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.
Hizmetleri, cihaz makefile'indeki RELEASE_AIDL_USE_UNFROZEN
işaretinin değerine göre koşullu olarak ekleyebilirsiniz:
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şse ve kaydedilemediyse
işlemi iptal edebilir. Beyan edilmemişse kaydedilememesi beklenir.
Bir geliştirme aracı olarak mürekkep balığı
VINTF dondurulduktan sonra her yıl, çerçeve uyumluluk matrisini (FCM) target-level
ve Cuttlefish'in PRODUCT_SHIPPING_API_LEVEL
değerini gelecek yılın sürümüyle kullanıma sunulan cihazları yansıtacak şekilde ayarlarız. target-level
ve PRODUCT_SHIPPING_API_LEVEL
değerlerini, test edilmiş ve gelecek yılki sürüm için yeni şartları karşılayan bir lansman cihazı olduğundan emin olmak üzere düzenleriz.
RELEASE_AIDL_USE_UNFROZEN
true
olduğunda Cuttlefish, gelecekteki Android sürümlerinin geliştirilmesi için kullanılır. Gelecek yılki Android sürümünün FCM düzeyini ve PRODUCT_SHIPPING_API_LEVEL
'ü hedefler. Bu nedenle, sonraki sürümün Tedarikçi Yazılım Şartları'nı (VSR) karşılaması gerekir.
RELEASE_AIDL_USE_UNFROZEN
false
olduğunda Cuttlefish, sürüm cihazını yansıtmak için önceki target-level
ve PRODUCT_SHIPPING_API_LEVEL
değerine sahiptir.
Android 14 ve önceki sürümlerde bu ayrım, FCM target-level
, gönderim API seviyesi veya sonraki sürümü hedefleyen başka bir kodda yapılan değişikliği içermeyen farklı Git dallarıyla gerçekleştirilir.
Modül adlandırma kuralları
Android 11'de, etkinleştirilen sürüm ve arka uçların her kombinasyonu için otomatik olarak bir taslak kitaplık modülü oluşturulur. Bağlantı oluşturmak için belirli bir stub kitaplık modülüne atıfta bulunmak üzere aidl_interface
modülünün adını değil, stub kitaplık modülünün adını kullanın. Bu ad ifacename-version-backend şeklindedir.
ifacename
:aidl_interface
modülünün adıversion
şu değerlerden biri olmalıdır:- Dondurulmuş sürümler için
Vversion-number
- Şu tarih için
Vlatest-frozen-version-number + 1
: ağaç ucu (henüz dondurulmuş) versiyonu
- Dondurulmuş sürümler için
backend
şunlardan biridir:- Java arka ucu için
java
, - C++ arka ucu için
cpp
, - NDK arka ucu için
ndk
veyandk_platform
. Birincisi uygulamalar içindir, İkincisi ise Android 13'e kadar platform kullanımı içindir. Android 13 ve sonraki sürümlerde yalnızcandk
kullanın. - Rust arka uç için
rust
.
- Java arka ucu için
foo adlı bir modülün olduğunu, en son sürümünün 2 olduğunu ve hem NDK hem de C++'yu desteklediğini varsayalım. Bu durumda AIDL aşağıdaki modülleri oluşturur:
- Sürüm 1'e göre
foo-V1-(java|cpp|ndk|ndk_platform|rust)
- 2. sürüme (en son kararlı sürüm) dayalı
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:
- En son kararlı sürümü belirten
foo-backend
,foo-V2-backend
olur. foo-unstable-backend
, (Hizmet Şartları'na atıfta bulunuluyor) sürümfoo-V3-backend
olur
Çıkış dosyası adları her zaman modül adlarıyla aynıdır.
- 1. sürüme dayalı:
foo-V1-(cpp|ndk|ndk_platform|rust).so
- 2. sürüme dayalı:
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, istikrarlı bir AIDL arayüzü için unstable
sürüm modülü veya sürüm içermeyen bir modül oluşturmadığını unutmayın.
Android 12'den itibaren, kararlı bir AIDL arayüzünden oluşturulan modül adı her zaman sürümünü içerir.
Yeni meta arayüz yöntemleri
Android 10, kararlı AIDL için çeşitli meta arayüz yöntemleri ekler.
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 uç örneği:
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 dilinde uzak taraf, getInterfaceVersion()
ve getInterfaceHash()
'yi aşağıdaki gibi UYGULAMALIDIR (kopyala ve yapıştırma hatalarını önlemek için IFoo
yerine super
kullanılır. javac
yapılandırmasına bağlı olarak uyarıları devre dışı bırakmak için @SuppressWarnings("static")
ek açıklama gerekebilir):
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, arayüzün eski bir sürümüyle oluşturulmuş olsa bile sınıfların en yeni sürümüne de bağlanır. Bu meta arayüz paylaşılan sınıfta uygulanırsa 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 çalışma
İstemciler, AIDL'nin yeni sürümüyle güncellenmiş olabilir
arayüzü ancak sunucu eski AIDL arayüzünü kullanıyor. Bu tür durumlarda, eski bir arayüzde bir yöntem çağrıldığında UNKNOWN_TRANSACTION
döndürülü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 uygulamadaki bir yöntem yalnızca uzak tarafta uygulanmadığında (arayüzün eski bir sürümüyle oluşturulduğu için) çağrılır. Varsayılanlar global olarak ayarlandığından, paylaşılabilir bağlamlarda kullanılmamalıdır.
Android 13 ve sonraki sürümlerde C++ dilinde ö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(...);
Bir AIDL arayüzündeki tüm yöntemlerin varsayılan uygulamasını sağlamanız gerekmez. 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ürme
Mevcut bir AIDL arayüzünüz ve bu arayüzü kullanan kodunuz varsa arayüzü kararlı bir AIDL arayüzüne dönüştürmek için aşağıdaki adımları uygulayın.
Arayüzünüzün tüm bağımlılıklarını tanımlayın. 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.
Arayüzünüzdeki tüm paketlenebilir öğeleri kararlı paketlenebilir öğelere dönüştürün (arayüz dosyalarının kendisi 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ılmalıdır. Bu işlem,
aidl_interface
paketi oluşturmadan önce (aşağıda) yapılabilir.Ş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. Verilerin sabitlenmesi için (yalnızca yapılandırılmış olması değil) sürümlendirilmesi de gerekir. Daha fazla bilgi için Sürüm oluşturma arayüzleri konusuna bakın.