החל מ-Android 12, אפשר להשתמש בתור הודעות מהיר עם ממשקי AIDL באמצעות קצה העורפי של NDK. התהליך הזה מאפשר לתהליכים לתקשר בלי התקורה וההגבלות של עסקאות binder אחרי הגדרה קצרה. שימוש ב-AIDL יציב מאפשר תקשורת בין תהליכי מערכת ותהליכי ספקים.
סוגי מטען ייעודי (Payload) נתמכים
FixedSizeסוגי AIDL (לא זמינים מהקצה העורפיcpp)parcelable- סוגי AIDL
union(לא זמינים מהקצה העורפיcpp) - סוגי
enumAIDL - סוגים של מספרים שלמים ב-AIDL
ההודעות שנשלחות בין תהליכים בתור ההודעות של הזיכרון המשותף צריכות להיות בעלות פריסת זיכרון זהה בגבולות התהליך, ולא יכולות להכיל מצביעים. ניסיון ליצור AidlMessageQueue עם סוג שלא נתמך גורם לשגיאת קומפילציה. אי אפשר להשתמש בסוגים parcelable ו-union של AIDL ב-cpp backend עם Fast Message Queue כי הם עוברים בירושה מ-android::Parcelable, שיש לו פונקציות וירטואליות.
סוגי תורים נתמכים
אותם סוגי תורים מ-HIDL, שלעתים קרובות נקראים flavors, נתמכים ב-AIDL. הם משמשים כארגומנטים של תבניות לתורים ולתיאורים.
| סוגי HIDL | סוגי AIDL |
|---|---|
android::hardware::kSynchronizedReadWrite |
android.hardware.common.fmq.SynchronizedReadWrite |
android::hardware::kUnsynchronizedWrite |
android.hardware.common.fmq.UnsynchronizedWrite |
איך משתמשים
מגדירים את ממשק ה-AIDL שמעביר את MQDescriptor לתהליך השני. אפשר להשתמש ב-MQDescriptor בכל מקום שבו אפשר להשתמש ב-Parcelable.
ארגומנטי התבנית הנדרשים עבור MQDescriptor הם סוג המטען הייעודי (payload) וסוג התור.
import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite
void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);
תהליך ההגדרה של כל צד בתור ההודעות כמעט זהה לתהליך באמצעות HIDL, רק שהוא מתבצע באמצעות סוגי AIDL.
#include <fmq/AidlMessageQueue.h>
...
using ::android::AidlMessageQueue;
using ::aidl::android::hardware::common::fmq::MQDescriptor;
using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
...
ndk::ScopedAStatus MyInterface::getQueue(MQDescriptor<int32_t, SynchronizedReadWrite>* mqDesc) {
*mqDesc = mFmqSynchronized->dupeDesc();
return ndk::ScopedAStatus::ok();
}
...
// Create the first side of the queue before servicing getQueue() in this example
mFmqSynchronized =
new AidlMessageQueue<int32_t, SynchronizedReadWrite>(kNumElementsInQueue);
תהליך הקבלה יוצר את הצד השני של התור עם המתאר שהתקבל מממשק AIDL.
MQDescriptor<int32_t, SynchronizedReadWrite> desc;
auto ret = service->getQueue(true, &desc);
if (!ret.isOk()) {
...
}
// By default the constructor will reset the read and write pointers of the queue.
// Add a second `false` argument to avoid resetting the pointers.
mQueue = new (std::nothrow) AidlMessageQueue<int32_t, SynchronizedReadWrite>(desc);
if (!mQueue->isValid()) {
...
}
השימוש ב-AidlMessageQueue אחרי ההגדרה זהה לשימוש ב-MessageQueue של HIDL.
כל ממשקי ה-API שמתוארים במאמר שימוש ב-MessageQueue נתמכים באופן מלא ב-AidlMessageQueue, למעט מקרה אחד:
const MQDescriptor<T, flavor>* getDesc() מוחלף ב-MQDescriptor<T, U> dupeDesc()
שמחזיר את AIDL MQDescriptor.