Bir AIDL arka ucu, saplama kodu üretimi için bir hedeftir. AIDL dosyalarını kullanırken, bunları her zaman belirli bir çalışma zamanı ile belirli bir dilde kullanırsınız. Bağlama bağlı olarak, farklı AIDL arka uçları kullanmalısınız.
AIDL aşağıdaki arka uçlara sahiptir:
arka uç | Dil | API yüzeyi | Yapı sistemleri |
---|---|---|---|
java | java | SDK/SystemApi (kararlı*) | herşey |
NDK | C++ | libbinder_ndk (sabit*) | aidl_interface |
CPP | C++ | libbinder (kararsız) | herşey |
Pas | Pas | libbinder_rs (kararsız) | aidl_interface |
- Bu API yüzeyleri kararlıdır, ancak hizmet yönetimi için olanlar gibi birçok API dahili platform kullanımı için ayrılmıştır ve uygulamalar tarafından kullanılamaz. AIDL'nin uygulamalarda nasıl kullanılacağı hakkında daha fazla bilgi için geliştirici belgelerine bakın.
- Rust arka ucu Android 12'de tanıtıldı; NDK arka ucu, Android 10'dan itibaren kullanıma sunulmuştur.
- Rust kasası,
libbinder_ndk
üzerine kuruludur. APEX'ler, ciltleme kasasını sistem tarafındaki diğer herkesle aynı şekilde kullanır. Rust kısmı bir APEX'e paketlenir ve içinde gönderilir. Sistem bölümündekilibbinder_ndk.so
bağlıdır.
Yapı sistemleri
Arka uca bağlı olarak, AIDL'yi saplama kodunda derlemenin iki yolu vardır. Derleme sistemleri hakkında daha fazla ayrıntı için Soong Modülü Referansına bakın.
Çekirdek yapı sistemi
Herhangi bir cc_
veya java_
Android.bp modülünde (veya bunların Android.mk
eşdeğerlerinde), .aidl
dosyaları kaynak dosyalar olarak belirtilebilir. Bu durumda AIDL'nin Java/CPP arka uçları kullanılır (NDK arka ucu değil) ve karşılık gelen AIDL dosyalarını kullanacak sınıflar otomatik olarak modüle eklenir. Derleme sistemine söz konusu modüldeki AIDL dosyalarının kök yolunu söyleyen local_include_dirs
gibi seçenekler, bu modüllerde bir aidl:
grubu altında belirtilebilir. Rust arka ucunun yalnızca Rust ile kullanım için olduğunu unutmayın. rust_
modülleri, AIDL dosyalarının kaynak dosyalar olarak belirtilmemesi nedeniyle farklı şekilde ele alınır. Bunun yerine aidl_interface
modülü, <aidl_interface name>-rust
adlı ve ona karşı bağlanabilen bir rustlib
üretir. Daha fazla ayrıntı için Rust AIDL örneğine bakın.
aidl_interface
Kararlı AIDL'ye bakın. Bu yapı sistemiyle kullanılan türler yapılandırılmalıdır; yani doğrudan AIDL'de ifade edilir. Bu, özel parsellenebilirlerin kullanılamayacağı anlamına gelir.
Türler
aidl
derleyicisini türler için bir referans uygulaması olarak düşünebilirsiniz. Bir arabirim oluşturduğunuzda, ortaya çıkan arabirim dosyasını görmek için aidl --lang=<backend> ...
. aidl_interface
modülünü kullandığınızda, çıktıyı out/soong/.intermediates/<path to module>/
içinde görüntüleyebilirsiniz.
Java/AIDL Türü | C++ Türü | NDK Tipi | Pas Tipi |
---|---|---|---|
mantıksal | bool | bool | bool |
bayt | int8_t | int8_t | i8 |
karakter | char16_t | char16_t | u16 |
int | int32_t | int32_t | i32 |
uzun | int64_t | int64_t | i64 |
batmadan yüzmek | batmadan yüzmek | batmadan yüzmek | f32 |
çift | çift | çift | f64 |
Sicim | android::Dize16 | std::dize | Sicim |
android.os.Parcelable | android::Parcelable | Yok | Yok |
Bağlayıcı | android::IBinder | ndk::SpAIBinder | bağlayıcı::SpIBinder |
T[] | std::vektör<T> | std::vektör<T> | İçinde: &[T] Çıkış: Vec<T> |
bayt[] | std::vector<uint8_t> | std::vector<int8_t> 1 | İçinde: &[u8] Çıkan: Vec<u8> |
Liste<T> | std::vector<T> 2 | std::vector<T> 3 | İçinde: &[T] 4 Çıkış: Vec<T> |
Dosya Tanımlayıcı | android::base::unique_fd | Yok | bağlayıcı::parcel::ParcelFileDescriptor |
ParselDosyaTanımlayıcı | android::os::ParcelFileDescriptor | ndk::ScopedFileDescriptor | bağlayıcı::parcel::ParcelFileDescriptor |
arayüz tipi (T) | android::sp<T> | std::shared_ptr<T> | bağlayıcı::Güçlü |
parsellenebilir tip (T) | T | T | T |
rakor tipi (T) 5 | T | T | T |
T[N] 6 | std::array<T, N> | std::array<T, N> | [T; N] |
1. Android 12 veya üzerinde, bayt dizileri uyumluluk nedenleriyle int8_t yerine uint8_t kullanır.
2. C++ arka ucu List<T>
destekler; burada T
, String
, IBinder
, ParcelFileDescriptor
veya parsellenebilirdir. Android 13 veya sonraki sürümlerde T
, diziler dışında herhangi bir ilkel olmayan tür olabilir (arayüz türleri dahil). AOSP, tüm arka uçlarda çalıştıkları için T[]
gibi dizi türlerini kullanmanızı önerir.
3. NDK arka ucu, T'nin String
, ParcelFileDescriptor
veya parsellenebilir değerlerden biri olduğu List<T>
T
destekler. Android 13 veya sonraki sürümlerde T
, diziler dışında herhangi bir ilkel olmayan tür olabilir.
4. Türler, giriş (argüman) veya çıkış (döndürülen değer) olmalarına bağlı olarak Rust kodu için farklı şekilde iletilir.
5. Birleşim türleri, Android 12 ve sonraki sürümlerde desteklenir.
6. Android 13 veya sonraki sürümlerde sabit boyutlu diziler desteklenir. Sabit boyutlu dizilerin birden çok boyutu olabilir (ör. int[3][4]
). Java arka ucunda, sabit boyutlu diziler, dizi türleri olarak temsil edilir.
Yönlülük (giriş/çıkış/giriş)
İşlevler için bağımsız değişken türlerini belirtirken, bunları in
, out
veya inout
olarak belirtebilirsiniz. Bu, bir IPC çağrısı için hangi yön bilgisinin iletildiğini kontrol eder. in
varsayılan yöndür ve arayandan aranana verilerin iletildiğini gösterir. out
, verilerin aranandan arayana iletildiği anlamına gelir. inout
, bunların her ikisinin birleşimidir. Ancak Android ekibi, inout
bağımsız değişken belirticisini kullanmaktan kaçınmanızı önerir. inout
sürümlü bir arabirim ve daha eski bir arananla kullanırsanız, yalnızca arayanda bulunan ek alanlar varsayılan değerlerine sıfırlanır. Rust ile ilgili olarak, normal bir giriş tipi &mut inout
&mut Vec<T>
alır ve bir liste giriş tipi &mut Vec<T>
inout
.
UTF8/UTF16
CPP arka ucu ile dizelerin utf-8 veya utf-16 olmasını seçebilirsiniz. Dizeleri otomatik olarak utf-8'e dönüştürmek için AIDL'de @utf8InCpp String
olarak bildirin. NDK ve Rust arka uçları her zaman utf-8 dizelerini kullanır. utf8InCpp
ek açıklaması hakkında daha fazla bilgi için bkz. AIDL'deki Ek Açıklamalar .
Nullabilite
Boş değerleri CPP ve NDK arka uçlarına göstermek için Java arka ucunda boş @nullable
ile açıklama ekleyebilirsiniz. Rust arka ucunda bu @nullable
türleri Option<T>
olarak gösterilir. Yerel sunucular, boş değerleri varsayılan olarak reddeder. Bunun tek istisnası, NDK okumaları ve CPP/NDK yazmaları için her zaman boş olabilen interface
ve IBinder
türleridir. nullable
yapılabilir açıklama hakkında daha fazla bilgi için bkz . AIDL'deki Ek Açıklamalar .
Özel Parseller
Çekirdek derleme sistemindeki C++ ve Java arka uçlarında, bir hedef arka uçta (C++ veya Java'da) manuel olarak uygulanan bir ayrıştırılabilir bildirebilirsiniz.
package my.package;
parcelable Foo;
veya C++ başlık bildirimi ile:
package my.package;
parcelable Foo cpp_header "my/package/Foo.h";
Daha sonra bu parsellenebiliri AIDL dosyalarında bir tür olarak kullanabilirsiniz, ancak AIDL tarafından oluşturulmayacaktır.
Rust, özel paketlenebilir öğeleri desteklemez.
Varsayılan değerler
Yapılandırılmış parsellenebilir öğeler, bu türlerdeki ilkel öğeler, String
s ve diziler için alan başına varsayılan değerler bildirebilir.
parcelable Foo {
int numField = 42;
String stringField = "string value";
char charValue = 'a';
...
}
Java arka ucunda, varsayılan değerler eksik olduğunda alanlar, ilkel türler için sıfır değerleri ve ilkel olmayan türler için null
değer olarak başlatılır.
Diğer arka uçlarda, varsayılan değerler tanımlanmadığında alanlar, varsayılan olarak başlatılan değerlerle başlatılır. Örneğin, C++ arka ucunda, String
alanları boş bir dize olarak başlatılır ve List<T>
alanları boş bir vector<T>
olarak başlatılır. @nullable
alanlar, boş değerli alanlar olarak başlatılır.
Hata yönetimi
Android işletim sistemi, hizmetlerin hataları bildirirken kullanması için yerleşik hata türleri sağlar. Bunlar bağlayıcı tarafından kullanılır ve bir bağlayıcı arabirimi uygulayan herhangi bir hizmet tarafından kullanılabilir. Kullanımları AIDL tanımında iyi bir şekilde belgelenmiştir ve herhangi bir kullanıcı tanımlı durum veya dönüş türü gerektirmezler.
Hatalı çıktı parametreleri
Bir AIDL işlevi bir hata bildirdiğinde, işlev çıkış parametrelerini başlatamayabilir veya değiştiremeyebilir. Spesifik olarak, hata, işlemin kendisinin işlenmesi sırasında meydana gelmesinin aksine ayrıştırma sırasında meydana gelirse, çıktı parametreleri değiştirilebilir. Genel olarak, bir inout
işlevinden hata alırken, tüm giriş ve out
parametrelerinin yanı sıra (bazı arka uçlarda out
parametresi gibi davranan) dönüş değerinin belirsiz durumda olduğu düşünülmelidir.
Hangi hata değerlerinin kullanılacağı
Yerleşik hata değerlerinin çoğu, herhangi bir AIDL arayüzünde kullanılabilir, ancak bazıları özel bir şekilde ele alınır. Örneğin, EX_UNSUPPORTED_OPERATION
ve EX_ILLEGAL_ARGUMENT
, hata koşulunu tanımladıklarında kullanılabilirler, ancak EX_TRANSACTION_FAILED
, altta yatan altyapı tarafından özel olarak ele alındığı için kullanılmamalıdır. Bu yerleşik değerler hakkında daha fazla bilgi için arka uca özgü tanımları kontrol edin.
AIDL arabirimi yerleşik hata türlerinin kapsamadığı ek hata değerleri gerektiriyorsa, kullanıcı tarafından tanımlanan hizmete özgü bir hata değerinin eklenmesine izin veren özel hizmete özgü yerleşik hatayı kullanabilirler. . Bu hizmete özgü hatalar, genellikle AIDL arayüzünde bir const int
veya int
-backed enum
olarak tanımlanır ve bağlayıcı tarafından ayrıştırılmaz.
Java'da hatalar, android.os.RemoteException
gibi istisnalarla eşlenir. Hizmete özgü istisnalar için Java, kullanıcı tanımlı hatayla birlikte android.os.ServiceSpecificException
kullanır.
Android'deki yerel kod istisnalar kullanmaz. CPP arka ucu android::binder::Status
kullanır. NDK arka ucu ndk::ScopedAStatus
kullanır. AIDL tarafından oluşturulan her yöntem, yöntemin durumunu temsil eden bunlardan birini döndürür. Rust arka ucu, NDK ile aynı istisna kodu değerlerini kullanır, ancak bunları kullanıcıya teslim etmeden önce yerel Rust hatalarına ( StatusCode
, ExceptionCode
) dönüştürür. Hizmete özgü hatalar için döndürülen Status
veya EX_SERVICE_SPECIFIC
, kullanıcı tanımlı hatayla birlikte ScopedAStatus
kullanır.
Yerleşik hata türleri aşağıdaki dosyalarda bulunabilir:
arka uç | Tanım |
---|---|
java | android/os/Parcel.java |
CPP | binder/Status.h |
NDK | android/binder_status.h |
Pas | android/binder_status.h |
Çeşitli arka uçları kullanma
Bu talimatlar, Android platform koduna özeldir. Bu örnekler, tanımlanmış bir tür kullanır, my.package.IFoo
. Rust arka ucunun nasıl kullanılacağına ilişkin talimatlar için Android Rust Modelleri sayfasındaki Rust AIDL örneğine bakın.
Türleri içe aktarma
Tanımlanan tür bir arabirim, ayrıştırılabilir veya birleşim olabilir, onu Java'ya aktarabilirsiniz:
import my.package.IFoo;
Veya CPP arka ucunda:
#include <my/package/IFoo.h>
Veya NDK arka ucunda (ekstra aidl
ad alanına dikkat edin):
#include <aidl/my/package/IFoo.h>
Veya Rust arka ucunda:
use my_package::aidl::my::package::IFoo;
Java'da yuvalanmış bir türü içe aktarabilmenize rağmen, CPP/NDK arka uçlarında kök türü için başlığı dahil etmeniz gerekir. Örneğin, my/package/IFoo.aidl
( IFoo
, dosyanın kök türüdür) içinde tanımlanan iç içe geçmiş bir Bar
türünü içe aktarırken, CPP arka ucu (veya <aidl/my/package/IFoo.h>
) için <my/package/IFoo.h>
eklemelisiniz. NDK arka ucu için <aidl/my/package/IFoo.h>
).
Uygulama hizmetleri
Bir hizmeti uygulamak için yerel saplama sınıfından miras almanız gerekir. Bu sınıf, ciltleyici sürücüsünden gelen komutları okur ve uyguladığınız yöntemleri yürütür. Bunun gibi bir AIDL dosyanız olduğunu hayal edin:
package my.package;
interface IFoo {
int doFoo();
}
Java'da, bu sınıftan genişletmeniz gerekir:
import my.package.IFoo;
public class MyFoo extends IFoo.Stub {
@Override
int doFoo() { ... }
}
CPP arka ucunda:
#include <my/package/BnFoo.h>
class MyFoo : public my::package::BnFoo {
android::binder::Status doFoo(int32_t* out) override;
}
NDK arka ucunda (ekstra aidl
ad alanına dikkat edin):
#include <aidl/my/package/BnFoo.h>
class MyFoo : public aidl::my::package::BnFoo {
ndk::ScopedAStatus doFoo(int32_t* out) override;
}
Rust arka ucunda:
use aidl_interface_name::aidl::my::package::IFoo::{BnFoo, IFoo};
use binder;
/// This struct is defined to implement IRemoteService AIDL interface.
pub struct MyFoo;
impl Interface for MyFoo {}
impl IFoo for MyFoo {
fn doFoo(&self) -> binder::Result<()> {
...
Ok(())
}
}
Kayıt olma ve hizmet alma
Android platformundaki hizmetler genellikle servicemanager
yöneticisi işlemiyle kaydedilir. Aşağıdaki API'lere ek olarak, bazı API'ler hizmeti kontrol eder (yani hizmet mevcut değilse hemen geri dönerler). Kesin ayrıntılar için ilgili servicemanager
yöneticisi arayüzünü kontrol edin. Bu işlemler yalnızca platform Android'e karşı derlenirken yapılabilir.
Java'da:
import android.os.ServiceManager;
// registering
ServiceManager.addService("service-name", myService);
// return if service is started now
myService = IFoo.Stub.asInterface(ServiceManager.checkService("service-name"));
// waiting until service comes up (new in Android 11)
myService = IFoo.Stub.asInterface(ServiceManager.waitForService("service-name"));
// waiting for declared (VINTF) service to come up (new in Android 11)
myService = IFoo.Stub.asInterface(ServiceManager.waitForDeclaredService("service-name"));
CPP arka ucunda:
#include <binder/IServiceManager.h>
// registering
defaultServiceManager()->addService(String16("service-name"), myService);
// return if service is started now
status_t err = checkService<IFoo>(String16("service-name"), &myService);
// waiting until service comes up (new in Android 11)
myService = waitForService<IFoo>(String16("service-name"));
// waiting for declared (VINTF) service to come up (new in Android 11)
myService = waitForDeclaredService<IFoo>(String16("service-name"));
NDK arka ucunda (ekstra aidl
ad alanına dikkat edin):
#include <android/binder_manager.h>
// registering
status_t err = AServiceManager_addService(myService->asBinder().get(), "service-name");
// return if service is started now
myService = IFoo::fromBinder(SpAIBinder(AServiceManager_checkService("service-name")));
// is a service declared in the VINTF manifest
// VINTF services have the type in the interface instance name.
bool isDeclared = AServiceManager_isDeclared("android.hardware.light.ILights/default");
// wait until a service is available (if isDeclared or you know it's available)
myService = IFoo::fromBinder(SpAIBinder(AServiceManager_waitForService("service-name")));
Rust arka ucunda:
use myfoo::MyFoo;
use binder;
use aidl_interface_name::aidl::my::package::IFoo::BnFoo;
fn main() {
binder::ProcessState::start_thread_pool();
// [...]
let my_service = MyFoo;
let my_service_binder = BnFoo::new_binder(
my_service,
BinderFeatures::default(),
);
binder::add_service("myservice", my_service_binder).expect("Failed to register service?");
// Does not return - spawn or perform any work you mean to do before this call.
binder::ProcessState::join_thread_pool()
}
ölüme bağlama
Bağlayıcı barındıran bir hizmet öldüğünde bildirim almak için istekte bulunabilirsiniz. Bu, geri arama proxy'lerinin sızmasını önlemeye veya hata düzeltmeye yardımcı olabilir. Bu aramaları bağlayıcı proxy nesneleri üzerinde yapın.
- Java'da
android.os.IBinder::linkToDeath
kullanın. - CPP arka
android::IBinder::linkToDeath
. - NDK arka ucunda,
AIBinder_linkToDeath
kullanın. - Rust arka ucunda bir
DeathRecipient
nesnesi oluşturun, ardındanmy_binder.link_to_death(&mut my_death_recipient)
. Geri aramanın sahibiDeathRecipient
olduğu için, bildirim almak istediğiniz sürece o nesneyi canlı tutmanız gerektiğini unutmayın.
Arayan bilgisi
Bir çekirdek bağlayıcı çağrısı alırken, arayan bilgisi birkaç API'de bulunur. PID (veya İşlem Kimliği), işlem gönderen işlemin Linux işlem kimliğini ifade eder. UID (veya Kullanıcı Kimliği), Linux kullanıcı kimliğini ifade eder. Tek yönlü bir çağrı alırken, arayan PID 0'dır. Bağlayıcı işlem bağlamının dışındayken, bu işlevler geçerli sürecin PID'sini ve UID'sini döndürür.
Java arka ucunda:
... = Binder.getCallingPid();
... = Binder.getCallingUid();
CPP arka ucunda:
... = IPCThreadState::self()->getCallingPid();
... = IPCThreadState::self()->getCallingUid();
NDK arka ucunda:
... = AIBinder_getCallingPid();
... = AIBinder_getCallingUid();
Rust arka ucunda, arabirimi uygularken aşağıdakileri belirtin (varsayılan olmasına izin vermek yerine):
... = ThreadState::get_calling_pid();
... = ThreadState::get_calling_uid();
Hizmetler için hata raporları ve hata ayıklama API'si
Hata raporları çalıştırıldığında (örneğin, adb bugreport
ile), çeşitli sorunların hatalarını gidermeye yardımcı olmak için sistemin her yerinden bilgi toplarlar. dumpsys
hizmetleri için hata raporları, bilgilerini hata raporuna dökmek için hizmet yöneticisine kayıtlı tüm hizmetlerde ikili döküm sistemlerini kullanır. dumpsys SERVICE [ARGS]
ile bir hizmetten bilgi almak için komut dumpsys
de kullanabilirsiniz. C++ ve Java arka uçlarında, addService
için ek bağımsız değişkenler kullanarak hizmetlerin boşaltılma sırasını kontrol edebilirsiniz. Hata ayıklama sırasında bir hizmetin PID'sini almak için dumpsys --pid SERVICE
de kullanabilirsiniz.
Hizmetinize özel çıktı eklemek için, bir AIDL dosyasında tanımlanan diğer herhangi bir IPC yöntemini uyguluyormuşsunuz gibi, sunucu nesnenizdeki dump
yöntemini geçersiz kılabilirsiniz. Bunu yaparken, android.permission.DUMP
uygulama izniyle veya belirli UID'lerle sınırlandırmalısınız.
Java arka ucunda:
@Override
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
@Nullable String[] args) {...}
CPP arka ucunda:
status_t dump(int, const android::android::Vector<android::String16>&) override;
NDK arka ucunda:
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
Rust arka ucunda, arabirimi uygularken aşağıdakileri belirtin (varsayılan olmasına izin vermek yerine):
fn dump(&self, mut file: &File, args: &[&CStr]) -> binder::Result<()>
Arayüz tanımlayıcısını dinamik olarak alma
Arayüz tanımlayıcısı, bir arayüzün tipini tanımlar. Bu, hata ayıklarken veya bilinmeyen bir klasörünüz olduğunda kullanışlıdır.
Java'da, arayüz tanımlayıcısını aşağıdaki gibi bir kodla alabilirsiniz:
service = /* get ahold of service object */
... = service.asBinder().getInterfaceDescriptor();
CPP arka ucunda:
service = /* get ahold of service object */
... = IInterface::asBinder(service)->getInterfaceDescriptor();
NDK ve Rust arka uçları bu işlevi desteklemez.
Arayüz tanımlayıcısını statik olarak alma
Bazen ( @VintfStability
servislerine kaydolurken olduğu gibi), arayüz tanımlayıcısının statik olarak ne olduğunu bilmeniz gerekir. Java'da, tanımlayıcıyı aşağıdaki gibi kod ekleyerek alabilirsiniz:
import my.package.IFoo;
... IFoo.DESCRIPTOR
CPP arka ucunda:
#include <my/package/BnFoo.h>
... my::package::BnFoo::descriptor
NDK arka ucunda (ekstra aidl
ad alanına dikkat edin):
#include <aidl/my/package/BnFoo.h>
... aidl::my::package::BnFoo::descriptor
Rust arka ucunda:
aidl::my::package::BnFoo::get_descriptor()
Enum Aralığı
Yerel arka uçlarda, bir numaralandırmanın alabileceği olası değerleri yineleyebilirsiniz. Kod boyutu hususları nedeniyle bu, şu anda Java'da desteklenmemektedir.
MyEnum
tanımlanan bir enum MyEnum için iterasyon aşağıdaki gibi sağlanır.
CPP arka ucunda:
::android::enum_range<MyEnum>()
NDK arka ucunda:
::ndk::enum_range<MyEnum>()
Rust arka ucunda:
MyEnum::enum_range()
Konu yönetimi
Bir süreçteki her libbinder
örneği bir iş parçacığı havuzunu korur. Çoğu kullanım durumu için bu, tüm arka uçlarda paylaşılan tam olarak bir iş parçacığı havuzu olmalıdır. Bunun tek istisnası, satıcı kodunun /dev/vndbinder
ile konuşmak için başka bir libbinder
kopyası yükleyebileceği zamandır. Bu, ayrı bir bağlayıcı düğümde olduğundan, iş parçacığı havuzu paylaşılmaz.
Java arka ucu için, iş parçacığı havuzunun boyutu yalnızca artabilir (çünkü zaten başlatılmıştır):
BinderInternal.setMaxThreads(<new larger value>);
CPP arka ucu için aşağıdaki işlemler mevcuttur:
// set max threadpool count (default is 15)
status_t err = ProcessState::self()->setThreadPoolMaxThreadCount(numThreads);
// create threadpool
ProcessState::self()->startThreadPool();
// add current thread to threadpool (adds thread to max thread count)
IPCThreadState::self()->joinThreadPool();
Benzer şekilde, NDK arka ucunda:
bool success = ABinderProcess_setThreadPoolMaxThreadCount(numThreads);
ABinderProcess_startThreadPool();
ABinderProcess_joinThreadPool();
Rust arka ucunda:
binder::ProcessState::start_thread_pool();
binder::add_service(“myservice”, my_service_binder).expect(“Failed to register service?”);
binder::ProcessState::join_thread_pool();
Ayrılmış İsimler
C++, Java ve Rust bazı adları anahtar sözcük olarak veya dile özgü kullanım için ayırır. AIDL, dil kurallarına dayalı kısıtlamalar uygulamasa da, ayrılmış bir adla eşleşen alan veya tür adlarının kullanılması, C++ veya Java için derleme hatasına neden olabilir. Rust için alan veya tür, r#
öneki kullanılarak erişilebilen "ham tanımlayıcı" sözdizimi kullanılarak yeniden adlandırılır.
Ergonomik olmayan bağlamalardan veya tamamen derleme hatasından kaçınmak için mümkün olduğunda AIDL tanımlarınızda ayrılmış adları kullanmaktan kaçınmanızı öneririz.
AIDL tanımlarınızda zaten ayrılmış adlarınız varsa, protokol uyumluluğunu korurken alanları güvenle yeniden adlandırabilirsiniz; oluşturmaya devam etmek için kodunuzu güncellemeniz gerekebilir, ancak önceden oluşturulmuş programlar birlikte çalışmaya devam edecektir.
Kaçınılması gereken isimler: * C++ Anahtar Kelimeleri * Java Anahtar Kelimeleri * Rust Anahtar Kelimeleri