اعتبارًا من Android 12، يمكن استخدام قائمة انتظار الرسائل السريعة مع واجهات AIDL باستخدام واجهة NDK الخلفية. يسمح ذلك للعمليات بالتواصل بدون النفقات العامة والقيود المفروضة على معاملات binder بعد عملية إعداد قصيرة. يسمح استخدام AIDL الثابت بالتواصل بين عمليات النظام وعمليات مورّد الجهاز.
أنواع حمولات البيانات المتوافقة
FixedSizeأنواع AIDLparcelable(غير متاحة من واجهةcppالخلفية)- أنواع
unionفي AIDL (غير متاحة من واجهةcppالخلفية) - أنواع
enumفي AIDL - أنواع الأعداد الصحيحة في AIDL
يجب أن يكون للرسائل المُرسَلة بين العمليات في قائمة انتظار الرسائل في الذاكرة المشترَكة تنسيق الذاكرة نفسه عبر حدود العمليات، ولا يمكن أن تحتوي على مؤشرات. تؤدي محاولة إنشاء AidlMessageQueue بنوع غير متوافق إلى حدوث خطأ في التجميع. لا يمكن استخدام أنواع parcelable وunion في AIDL في واجهة cpp الخلفية مع "قائمة انتظار الرسائل السريعة" لأنّها موروثة من android::Parcelable التي تتضمّن وظائف افتراضية.
أنواع قوائم الانتظار المتوافقة
تتوافق AIDL مع أنواع قوائم الانتظار نفسها من HIDL، والتي غالبًا ما تُسمّى "النكهات". تُستخدَم هذه الأنواع كمعلّمات للنماذج لقوائم الانتظار والأوصاف.
| أنواع HIDL | أنواع AIDL |
|---|---|
android::hardware::kSynchronizedReadWrite |
android.hardware.common.fmq.SynchronizedReadWrite |
android::hardware::kUnsynchronizedWrite |
android.hardware.common.fmq.UnsynchronizedWrite |
كيفية الاستخدام
حدِّد واجهة AIDL التي تنقل MQDescriptor إلى العملية الأخرى. يمكن استخدام MQDescriptor في أي مكان يمكن فيه استخدام `parcelable`.
معلّمات النموذج المطلوبة لـ MQDescriptor هي نوع حمولة البيانات ونكهة قائمة الانتظار.
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.
تتوافق جميع واجهات برمجة التطبيقات الموضّحة في مقالة استخدام MessageQueue بشكل كامل
مع AidlMessageQueue، باستثناء ما يلي:
يتم استبدال const MQDescriptor<T, flavor>* getDesc() بـ MQDescriptor<T, U> dupeDesc()
الذي يعرض MQDescriptor في AIDL.