החל מ-Android 12, אפשר להשתמש ב-Fast Message Queue עם ממשקי AIDL באמצעות קצה העורפי של NDK. השיטה הזו מאפשרת לתהליכים לתקשר בלי התקורה וההגבלות של עסקאות binder אחרי הגדרה קצרה. שימוש ב-Stable AIDL מאפשר תקשורת בין תהליכי מערכת ותהליכי ספק.
סוגי מטען ייעודי נתמכים
- סוגי AIDL
parcelable
עם הערה @FixedSize - סוגי
enum
AIDL - סוגים של מספרים שלמים ב-AIDL
ההודעות שנשלחות בין תהליכים בתור ההודעות של הזיכרון המשותף צריכות להיות בעלות פריסת זיכרון זהה בין גבולות התהליכים, ולא יכולות להכיל מצביעים. ניסיון ליצור AidlMessageQueue
עם סוג שלא נתמך יגרום לשגיאת קומפילציה.
סוגי תורים נתמכים
AIDL תומך באותם סוגי תורים מ-HIDL, שלעתים קרובות נקראים flavors. הם משמשים כארגומנטים של תבניות לתורים ולתיאורים.
סוגי 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
.