Android 10'a, AIDL arayüzleri tarafından sağlanan uygulama programı arayüzü (API) ve uygulama ikili programı arayüzünü (ABI) izlemenin yeni bir yolu olan kararlı Android Arayüz Tanımlama Dili (AIDL) desteği eklendi. Kararlı AIDL, AIDL'den şu temel farklara sahiptir:
- 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 ayrıştırıcılar, AIDL tanımlarına göre otomatik olarak oluşturulur, otomatik olarak sınırlandırılır ve işaretlenmez.
- Arayüzler kararlı (geriye dönük uyumlu) olarak bildirilebilir. Böyle bir durumda, API'leri izlenir ve AIDL arayüzünün yanındaki bir dosyada sürüm oluşturulur.
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 beyan (özel paket) yapılandırılmış AIDL değildir. AIDL'de tanımlanmış alanları bulunan ayrıştırıcılara yapılandırılmış ayrıştırılabilir adı verilir.
Derleme sisteminin ve derleyicinin, ayrıştırılabilir öğelerde yapılan değişikliklerin geriye dönük uyumlu olup olmadığını anlayabilmesi için kararlı AIDL, yapılandırılmış AIDL gerektirir.
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ürleri, ayrıca aşağıdaki sürüm oluşturma özelliklerini kullanması gerekir. Öte yandan, bir arayüz derlemek için temel derleme sistemi kullanılıyorsa veya unstable:true
ayarlanmışsa arayüz kararlı değildir.
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 AIDL arayüzünü benzersiz şekilde tanımlayan AIDL arayüz modülünün adı.srcs
: Arayüzü oluşturan AIDL kaynak dosyalarının listesi.com.acme
paketinde tanımlananFoo
AIDL türünün yolu<base_path>/com/acme/Foo.aidl
olmalıdır. Burada<base_path>
,Android.bp
bulunduğu dizinle ilişkili herhangi bir dizin olabilir. Önceki örnekte<base_path>
,srcs/aidl
değeridir.local_include_dir
: Paket adının başladığı yol. Yukarıda açıklanan<base_path>
özelliğine karşılık gelir.imports
: Bu uygulamanın kullandığıaidl_interface
modülün listesi. AIDL arayüzlerinizden birinde bir arayüz veya başka biraidl_interface
'den ayrıştırılabilir öğe kullanılıyorsa adını buraya girin. Bu ad, kendi başına bir ad, en yeni sürüme işaret etmek için kullanılan ad veya belirli bir sürümü belirtmek için sürüm sonekini içeren ad (ör.-V1
) olabilir. Sürüm belirtme, Android 12'den beri destekleniyorversions
: Arayüzünapi_dir
altında dondurulan önceki sürümleri, Android 11 sürümünden itibarenversions
aidl_api/name
altında dondurulmuştur. Bir arayüzün donmuş sürümü yoksa bu belirtilmemelidir ve uyumluluk kontrolleri yapılmayacaktır. Bu alan, Android 13 ve sonraki sürümlerdeversions_with_info
ile değiştirilmiştir.versions_with_info
: Her biri, dondurulmuş sürümün adını ve bu aidl_interface sürümünün içe aktardığı diğer aidl_interface modüllerinin sürüm içe aktarmalarını içeren bir liste içerir. AIDL arayüzünün V sürümünün tanımıaidl_api/IFACE/V
adresinde bulunmaktadır. Bu alan, Android 13'te kullanıma sunulmuştur ve doğrudanAndroid.bp
üzerinde değiştirilmesine gerek yoktur. Alan,*-update-api
veya*-freeze-api
çağrılarak eklenir veya güncellenir. Ayrıca, bir kullanıcı*-update-api
veya*-freeze-api
yöntemini çağırdığındaversions
alanları otomatik olarakversions_with_info
ürününe taşınır.stability
: Bu arayüzün kararlılık taahhüdüyle ilgili isteğe bağlı işarettir. Yalnızca"vintf"
desteklenir.stability
ayarlanmazsa derleme sistemi,unstable
belirtilmediği sürece arayüzün geriye dönük uyumlu olup olmadığını kontrol eder. Ayarlanmadan bırakılması, bu derleme bağlamında kararlılığa sahip bir arayüze karşılık gelir (yani örneğin,system.img
ve ilgili bölümlerdeki öğeler ya da tüm sağlayıcı öğeleri (örneğin,vendor.img
ve ilgili bölümlerdekiler)).stability
,"vintf"
değerine ayarlanırsa bu durum, kararlılık taahhüdüne karşılık gelir: Arayüz kullanıldığı sürece kararlı tutulmalıdır.gen_trace
: İzlemeyi açmak veya kapatmak için kullanılan isteğe bağlı işaret. Android 14'ten itibarencpp
vejava
arka uçları için varsayılan değertrue
şeklindedir.host_supported
:true
olarak ayarlandığında oluşturulan kitaplıkları ana makine ortamında kullanılabilir hale getiren isteğe bağlı işaret.unstable
: Bu arayüzün kararlı olması gerekmediğini işaretlemek için kullanılan isteğe bağlı işaret. Bu değertrue
olarak ayarlandığında, derleme sistemi arayüz için API dökümünü oluşturmaz veya güncellenmesini gerektirmez.frozen
:true
olarak ayarlandığında, arayüzün önceki sürümünden bu yana hiçbir değişiklik yapılmadığı anlamına gelen isteğe bağlı işaret. Bu sayede daha fazla derleme zamanı denetimi elde edebilirsiniz.false
olarak ayarlandığında bu, arayüzün geliştirildiği ve yeni değişiklikler yapıldığı anlamına gelir. Bu nedenle,foo-freeze-api
çalıştırmak yeni bir sürüm oluşturur ve değeri otomatik olaraktrue
şeklinde değiştirir. Android 14'te kullanıma sunuldu.backend.<type>.enabled
: Bu işaretler, AIDL derleyicinin kod oluşturduğu arka uçların her birini açar/kapatır. Java, C++, NDK ve Rust olmak üzere dört arka uç desteklenir. Java, C++ ve NDK arka uçları varsayılan olarak etkindir. Bu üç arka uçtan herhangi biri gerekli değilse açıkça devre dışı bırakılmalıdır. Rust, Android 15'e (AOSP deneysel) kadar varsayılan olarak devre dışıdır.backend.<type>.apex_available
: Oluşturulan saplama kitaplığının kullanılabildiği APEX adlarının listesi.backend.[cpp|java].gen_log
: İşlem hakkında 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 getiren isteğe bağlı işaret.false
varsayılandır.backend.[cpp|ndk].additional_shared_libraries
: Android 14'te kullanıma sunulan bu işaret, yerel kitaplıklara bağımlılık ekler. Bu işaret,ndk_header
vecpp_header
ile kullanışlıdır.backend.java.sdk_version
: Java saplama kitaplığının oluşturulduğu SDK sürümünü belirtmek için kullanılan isteğe bağlı işaret. Varsayılan değer"system_current"
'tir.backend.java.platform_apis
,true
olduğunda ayarlanmamalıdır.backend.java.platform_apis
: Oluşturulan kitaplıkların SDK yerine platform API'sine dayalı olarak derlemesi 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 kitaplığı oluşturulur. Belirli bir arka uç için saplama kitaplığının spesifik sürümüne nasıl referans verileceğini öğrenmek için Modül adlandırma kuralları bölümüne bakın.
AIDL dosyaları yazma
Kararlı AIDL'deki arayüzler, yapılandırılmamış ayrıştırıcılar kullanmalarına izin olmaması dışında geleneksel arayüzlere benzer (bu arayüzler kararlı değildir; Yapılandırılmış ve kararlı AIDL başlıklı makaleyi inceleyin). Kararlı AIDL'deki temel fark, parsellerin nasıl tanımlandığıdır. Daha önce, ayrıştırılabilir öğeler ileriye bildiriliyordu; kararlı durumda (ve dolayısıyla yapılandırılmış) AIDL'de, ayrıştırılabilir alanlar ve değişkenler açık bir şekilde tanımlanıyordu.
// 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 bir varsayılan desteklenir (ancak zorunlu değildir). Android 12'de, kullanıcı tanımlı numaralandırmaların varsayılanları da 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ı olmasa bile 0 olarak başlatılır.
Saplama kitaplıklarını kullanma
Modülünüze bağımlılık olarak saplama kitaplıklarını ekledikten sonra dosyalarınıza ekleyebilirsiniz. Derleme sistemindeki saplama kitaplıklarına ilişkin örnekleri aşağıda bulabilirsiniz (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 modülün API'sini yönetmek için kullanabileceğiniz bir hedef de oluşturulur. foo-jpeg-api, derlendiğinde Android sürümüne bağlı olarak api_dir
veya aidl_api/name
altına yeni bir API tanımı ekler ve her ikisi de arayüzün yeni dondurulmuş sürümünü temsil eden bir .hash
dosyası ekler. foo-jpeg-api, ek sürümü yansıtacak şekilde versions_with_info
özelliğini ve sürüm için imports
'u günceller. Temel olarak versions_with_info
içindeki imports
, imports
alanından kopyalanır. Ancak en son kararlı sürüm, açık bir sürümü olmayan içe aktarma işlemi için versions_with_info
içinde imports
için belirtilmiştir.
versions_with_info
özelliği belirtildikten sonra, derleme sistemi dondurulmuş sürümler arasında ve ayrıca Ağacın Üstü (ToT) ile en son dondurulmuş sürüm arasında uyumluluk kontrolleri çalıştırır.
Ayrıca, ToT sürümünün API tanımını da yönetmeniz gerekir. API güncellendiğinde, ToT sürümünün API tanımını içeren aidl_api/name/current
öğesini 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 sonuna kadar olan yöntemler (veya açık bir şekilde tanımlanmış yeni serilere sahip yöntemler)
- Ayrıştırılabilir bir öğenin sonuna eklenen öğeler (her öğe için bir varsayılan değer eklenmesini gerektirir)
- 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 hiç kimse arayüz üzerinde değişiklik yapamaz (aksi takdirde, sayfa sahibinin yaptığı değişikliklerle çakışma riski olur).
Tüm arayüzlerin yayınlanmak üzere dondurulduğunu test etmek için aşağıdaki çevre değişkenleri grubuyla derleme yapabilirsiniz:
AIDL_FROZEN_REL=true m ...
: Derleme,owner:
alanı belirtilmemiş tüm kararlı AIDL arayüzlerinin dondurulmasını gerektirir.AIDL_FROZEN_OWNERS="aosp test"
: Derleme, tüm kararlı AIDL arayüzlerinin "aosp" veya "test" olarak belirtilenowner:
alanıyla dondurulmasını gerektirir.
İthalatın kararlılığı
Bir arayüzün dondurulmuş sürümleri için içe aktarma sürümlerinin güncellenmesi, Kararlı AIDL katmanında geriye dönük uyumludur. Ancak bunların güncellenmesi, arayüzün önceki sürümünü kullanan tüm sunucuların ve istemcilerin güncellenmesini gerektirir. Farklı türlerin sürümlerini bir arada kullanırken bazı uygulamalar karışıklığa neden olabilir. Genellikle yalnızca türler veya genel paketler için bu güvenlidir çünkü IPC işlemlerinden bilinmeyen türleri işlemek üzere kodun daha önce yazılması gerekir.
Android platform kodundaki android.hardware.graphics.common
, bu sürüm yükseltme
türünün en büyük örneğidir.
Sürümlü arayüzleri kullanma
Arayüz yöntemleri
Çalışma zamanında, eski bir sunucuda yeni yöntemler çağırmaya çalışan yeni istemciler arka uca bağlı olarak hata veya istisna alır.
cpp
arka ucu::android::UNKNOWN_TRANSACTION
alır.ndk
arka ucuSTATUS_UNKNOWN_TRANSACTION
alır.java
arka ucu, API'nin uygulanmadığını belirten bir mesajlaandroid.os.RemoteException
alır.
Bunu ele alacak stratejiler için sorgu sürümleri ve varsayılanları kullanma bölümünü inceleyin.
Parseller
Parsellere yeni alanlar eklendiğinde, eski istemciler ve sunucular bunları bırakır. Yeni istemciler ve sunucular eski parselleri aldığında, yeni alanların varsayılan değerleri otomatik olarak doldurulur. Bu, ayrıştırılabilir öğedeki tüm yeni alanlar için varsayılanların belirtilmesi gerektiği anlamına gelir.
İstemciler, alanın tanımlanmış olduğu sürümü uyguladığını bilmedikleri sürece sunucuların yeni alanları kullanmasını beklememelidir (sorgu sürümleri bölümüne bakın).
Sıralamalar ve sabit değerler
Benzer şekilde, gelecekte daha fazla sabit değer eklenebileceği için, istemciler ve sunucular tanınmayan sabit değerleri ve numaralandırıcıları uygun şekilde reddetmeli veya yoksaymalıdır. Örneğin, bir sunucu, varlığından haberdar olmadığı bir numaralandırıcı aldığında işlemi iptal etmemelidir. Sunucu, numaralandırıcıyı yoksaymalı veya istemcinin bu uygulamada desteklenmediğini bilmesi için bir öğe döndürmelidir.
Birlikler
Alıcı eskiyse ve alanı bilmiyorsa yeni bir alanla bütünleştirme girişimi başarısız olur. Uygulama, yeni alanla bütünlüğü 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 ucu için) olur. İstemci yeni alana ayarlanmış bir bütünleştirmeyi eski bir sunucuya gönderdiğinde veya eski bir istemci yeni bir sunucudan birleştirme alan eski bir istemci olduğunda hata alınır.
Bayrağa dayalı geliştirme
Geliştirme aşamasındaki (dondurulmuş) arayüzler, geriye dönük uyumlu oldukları garanti edilmediğinden sürüm cihazlarında kullanılamaz.
AIDL, kodun dondurulmamış en son sürüme göre yazılması ve sürüm cihazlarında kullanılmaya devam edebilmesi için bu dondurulmuş arayüz kitaplıkları için çalışma zamanı yedeğini destekler. İstemcilerin geriye dönük uyumlu davranışı, mevcut davranışa benzerdir. Yedek sayesinde, uygulamaların da bu davranışlara uyması gerekir. Sürümlü arayüzleri kullanma bölümüne bakın.
AIDL derleme işareti
Bu davranışı kontrol eden işaret, build/release/build_flags.bzl
içinde tanımlanan RELEASE_AIDL_USE_UNFROZEN
şeklindedir. true
, arayüzün dondurulmuş sürümünün çalışma zamanında kullanıldığı, false
ise dondurulmuş sürümlerin kitaplıklarının tümünün dondurulmuş son sürümleri gibi davrandığı anlamına gelir.
Yerel geliştirme için işareti true
olarak geçersiz kılabilirsiniz ancak yayınlamadan önce false
değerine geri döndürmeniz gerekir. Genellikle geliştirme işlemi, işareti true
olarak ayarlanmış bir yapılandırmayla yapılır.
Uyumluluk matrisi ve manifest'ler
Tedarikçi firma arayüzü nesneleri (VINTF nesneleri) hangi sürümlerin beklendiğini ve tedarikçi arayüzünün her iki tarafında hangi sürümlerin sağlandığını tanımlar.
Cuttlefish dışındaki çoğu cihaz yalnızca arayüzler dondurulduktan sonra en son uyumluluk matrisini hedefler. Bu nedenle RELEASE_AIDL_USE_UNFROZEN
temelli AIDL kitaplıklarında herhangi bir fark yoktur.
Matrisler
İş ortağına ait arayüzler, geliştirme sırasında cihazın hedeflediği cihaza özel veya ürüne özgü uyumluluk matrislerine eklenir. Bu nedenle, bir arayüzün yeni ve dondurulmamış bir sürümü bir uyumluluk matrisine eklendiğinde, önceki dondurulmuş sürümlerin RELEASE_AIDL_USE_UNFROZEN=false
boyunca kalması gerekir. Bu durumu, farklı RELEASE_AIDL_USE_UNFROZEN
yapılandırmaları için farklı uyumluluk matrisi dosyaları kullanarak veya tüm yapılandırmalarda kullanılan tek bir uyumluluk matrisi dosyasında her iki sürüme izin vererek başarabilirsiniz.
Örneğin, dondurulmuş sürüm 4'ü eklerken <version>3-4</version>
değerini kullanın.
Sürüm 4 dondurulduğunda, RELEASE_AIDL_USE_UNFROZEN
false
olduğunda donmuş sürüm 4 kullanıldığından sürüm 3'ü uyumluluk matrisinden kaldırabilirsiniz.
Manifestler
Android 15'te (AOSP deneysel), derleme sırasında manifest dosyalarını RELEASE_AIDL_USE_UNFROZEN
değerine göre değiştirmek için libvintf
ürününde bir değişiklik yapıldı.
Manifest'ler ve manifest parçaları, bir hizmetin hangi arayüz sürümünü uyguladığını bildirir. Bir arayüzün en son dondurulmamış sürümü kullanılı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
ile düzenlenir. Bu sürüm,
dondurulmuş sürümden (N
) en son dondurulmuş sürüme N - 1
değiştirilir. Bu nedenle, kullanıcıların hizmetlerinin her biri için birden fazla manifesti veya manifest parçasını yönetmesi gerekmez.
HAL istemcisiyle ilgili değişiklikler
HAL istemci kodu, daha önce desteklenen her dondurulmuş sürümle geriye dönük uyumlu olmalıdır. RELEASE_AIDL_USE_UNFROZEN
değeri false
olduğunda hizmetler, her zaman son dondurulmuş sürüm veya önceki sürümler gibi görünür (örneğin, yeni dondurulmuş yöntemlerin çağrılması, UNKNOWN_TRANSACTION
değerini veya yeni parcelable
alanlarının varsayılan değerlerini döndürür). Android çerçeve istemcilerinin önceki ek sürümlerle geriye dönük uyumlu olması gerekir. Ancak bu, satıcı müşterileri 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ştirmede görülen en büyük fark, HAL uygulamalarının, RELEASE_AIDL_USE_UNFROZEN
false
olduğunda çalışacak son dondurulmuş sürümle geriye dönük uyumlu olma gerekliliğidir.
Uygulamalarda ve cihaz kodunda geriye dönük uyumluluğu göz önünde bulundurmak yeni bir uygulamadır. Sürümlü arayüzleri kullanma konusuna bakın.
Geriye dönük uyumlulukla ilgili dikkat edilmesi gereken noktalar genellikle istemciler ve sunucular ile çerçeve kodu ve tedarikçi kodu için aynıdır ancak artık aynı kaynak kodunu (mevcut, dondurulmamış sürüm) kullanan iki sürümü etkili bir şekilde uyguladığınız için bilmeniz gereken küçük farklılıklar vardır.
Örnek: Bir arayüzün dondurulmuş üç sürümü vardır. Arayüz yeni bir yöntemle
güncellendi. Hem istemci hem de hizmet, yeni sürüm 4 kitaplığını 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 gibi davranır ve yeni yöntemin kullanılmasını engeller.
Arayüz dondurulduğunda tüm RELEASE_AIDL_USE_UNFROZEN
değerleri dondurulmuş sürümü kullanır ve geriye dönük uyumluluğu işleyen kod kaldırılabilir.
Geri çağırma yöntemlerinde arama yaparken, UNKNOWN_TRANSACTION
döndürüldüğünde destek kaydını dikkatli bir şekilde ele almanız gerekir. İstemciler, sürüm yapılandırmasına bağlı olarak bir geri çağırmanın iki farklı sürümünü uyguluyor olabilir. Bu nedenle, istemcinin en yeni sürümü gönderdiğini varsayamazsınız ve yeni yöntemler bunu döndürebilir. Bu, kararlı AIDL istemcilerinin Sürümlü arayüzleri kullanma bölümünde açıklanan sunucularla geriye dönük uyumluluğu korumasına benzer.
// 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();
}
}
RELEASE_AIDL_USE_UNFROZEN
false
olduğunda ve bir hizmetin göndermeye çalıştığı yeni alanların değerleri işlemden çıkarıldığında mevcut türlerdeki (parcelable
, enum
, union
) yeni alanlar mevcut olmayabilir veya bunların varsayılan değerlerini içerebilir.
Bu dondurulmuş sürüme eklenen yeni türler arayüz üzerinden gönderilemez veya alınamaz.
RELEASE_AIDL_USE_UNFROZEN
false
olduğunda uygulama, hiçbir zaman istemcilerden yeni yöntemler çağrısı almaz.
Yeni numaralandırıcıları önceki sürümle değil, yalnızca sunuldukları sürümle kullanmaya dikkat edin.
Normalde, uzak arayüzün hangi sürümü kullandığını görmek için foo->getInterfaceVersion()
kullanırsınız. Ancak işaret tabanlı sürüm oluşturma desteği ile iki farklı sürüm uygularsınız. Bu nedenle, mevcut arayüzün sürümünü edinmek 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 bölümüne bakın.
Yeni VINTF kararlı arayüzleri
Yeni bir AIDL arayüz paketi eklendiğinde, son dondurulmuş sürüm olmaz. Bu nedenle, RELEASE_AIDL_USE_UNFROZEN
false
olduğunda geri alınacak bir davranış olmaz. Bu arayüzleri kullanmayın. RELEASE_AIDL_USE_UNFROZEN
değeri false
olduğunda Hizmet Yöneticisi, hizmetin arayüzü kaydetmesine izin vermez ve istemciler bunu bulmaz.
Hizmetleri, cihaz oluşturma dosyasındaki 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 bu nedenle cihaza koşullu olarak eklemeniz mümkün değilse hizmetin IServiceManager::isDeclared()
ile beyan edilip edilmediğini kontrol edebilirsiniz. Bildirildiyse ve kaydedilemediyse işlemi iptal edin. Beyan edilmemişse kaydedilemez.
Bir geliştirme aracı olarak mürekkep balığı
VINTF'in dondurulmasından sonra her yıl, çerçeve uyumluluk matrisi (FCM) target-level
ve Cuttlefish'in PRODUCT_SHIPPING_API_LEVEL
özelliklerini önümüzdeki yıl piyasaya sürülecek cihazları yansıtacak şekilde düzenliyoruz. Lansmanı yapılacak bazı cihazların test edilip önümüzdeki yıl kullanıma sunulacak yeni gereksinimleri karşıladığından emin olmak için target-level
ve PRODUCT_SHIPPING_API_LEVEL
üzerinde gerekli düzenlemeleri yapıyoruz.
RELEASE_AIDL_USE_UNFROZEN
true
olduğunda, Cuttlefish gelecekteki Android
sürümlerinin geliştirilmesi için kullanılır. Hedef, gelecek yılki Android sürümünün FCM seviyesini ve PRODUCT_SHIPPING_API_LEVEL
düzeyini hedefler, böylece sonraki sürümün Tedarikçi Yazılım Gereksinimlerini (VSR) karşılaması gerekir.
RELEASE_AIDL_USE_UNFROZEN
false
olduğunda Cuttlefish'te sürüm cihazı olarak önceki target-level
ve PRODUCT_SHIPPING_API_LEVEL
bulunur.
Android 14 ve önceki sürümlerde bu ayrım; FCM target-level
değişikliği, kargo API düzeyi veya sonraki sürümü hedefleyen başka herhangi bir kodla yapılan değişikliği almayan farklı Git dalları ile sağlanır.
Modül adlandırma kuralları
Android 11'de etkinleştirilen her bir sürüm ve arka uç kombinasyonu için otomatik olarak bir saplama kitaplığı modülü oluşturulur. Bağlama işlemi için belirli bir saplama kitaplığı modülüne başvurmak için aidl_interface
modülünün adını değil, saplama kitaplığı modülünün adını (ifacename-version-backend) kullanın.
ifacename
:aidl_interface
modülünün adıversion
şunlardan biridir:- Dondurulmuş sürümler için
Vversion-number
- ağaç ucu (henüz dondurulmuş) sürümü için
Vlatest-frozen-version-number + 1
- 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
. İlki uygulamalar için, ikincisi ise Android 13'e kadar platform kullanımı içindir. Android 13 ve sonraki sürümlerde yalnızcandk
uygulamasını kullanın. - Rust arka ucu için
rust
.
- Java arka ucu için
foo adında bir modülün olduğunu ve en son sürümünün 2 olduğunu ve hem NDK hem de C++'yı desteklediğini varsayalım. 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'ye (en son kararlı sürüm) dayalı olarak
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üme işaret eden
foo-backend
,foo-V2-backend
olur. - ToT sürümü olan
foo-unstable-backend
,foo-V3-backend
olarak değişir.
Çı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, kararlı bir AIDL arayüzü için unstable
sürüm modülü veya sürümü olmayan 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 onun 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 uyguladığı arayüzün sürümünü ve karmasını sorgulayabilir ve döndürülen değerleri, istemcinin kullandığı arayüz değerleriyle karşılaştırabilir.
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()
uygulamasını aşağıdaki gibi uygulaması gerekir (kopyalama 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çıklaması 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.) istemci ile sunucu arasında paylaşılmasıdır (örneğin, sınıflar önyükleme sınıf yolunda olabilir). Sınıflar paylaşıldığında, sunucu, arayüzün daha 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. Bununla birlikte, yukarıdaki yöntem uygulandığında, arayüzün sürüm numarası sunucunun koduna yerleştirilir (çünkü IFoo.VERSION
, başvuruda bulunulduğunda satır içine alınan bir static final int
öğesidir) ve böylece bu yöntem, sunucunun birlikte derlendiği sürümü tam olarak döndürebilir.
Eski arayüzlerle ilgilenin
Bir istemcinin AIDL arayüzünün yeni sürümüyle güncellenmiş ancak sunucunun eski AIDL arayüzünü kullanıyor olması mümkündür. Bu gibi durumlarda, eski bir arayüzde yöntem çağrıldığında UNKNOWN_TRANSACTION
değeri döndürülür.
Kararlı AIDL sayesinde istemciler daha fazla kontrole sahip olur. İstemci tarafında AIDL arayüzü için varsayılan uygulama ayarlayabilirsiniz. Varsayılan uygulamadaki bir yöntem, yalnızca yöntem uzak tarafta uygulanmadığında (arayüzün eski bir sürümüyle oluşturulduğundan) çağrılır. Varsayılanlar genel olarak ayarlandığından, potansiyel olarak paylaşılan bağlamlardan kullanılmamalıdır.
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 arayüzünde tüm yöntemlerin varsayılan uygulamasını sağlamanız gerekmez. Uzak tarafta uygulanması garanti edilen yöntemlerin (uzaktan kumandanın, AIDL arayüzü açıklamasında yer alan yöntemlerle oluşturulduğundan emin olmanız nedeniyle) varsayılan impl
sınıfında geçersiz kılınması gerekmez.
Mevcut AIDL'yi yapılandırılmış veya kararlı AIDL'ye dönüştürün
Mevcut bir AIDL arayüzü ve bunu 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ı belirleyin. Arayüzün bağlı olduğu her paket için paketin kararlı AIDL'de tanımlanıp tanımlanmadığını belirleyin. Tanımlanmamışsa paketin dönüştürülmesi gerekir.
Arayüzünüzdeki tüm ayrıştırılabilir öğeleri kararlı parsellere dönüştürün (arayüz dosyalarının kendileri değişmeden kalabilir). Bunu, yapılarını doğrudan AIDL dosyalarında ifade ederek yapabilirsiniz. Yönetim sınıfları bu yeni türleri kullanacak şekilde yeniden yazılmalıdır. Bu işlem, bir
aidl_interface
paketi (aşağıda) oluşturmadan önce yapılabilir.Modülünüzün adını, bağımlılıklarını ve ihtiyacınız olan diğer tüm bilgileri içeren bir
aidl_interface
paketi (yukarıda açıklandığı gibi) oluşturun. 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.