"قائمة الرسائل السريعة" باستخدام لغة تعريف واجهة نظام Android ‏(AIDL)

اعتبارًا من Android 12، يمكن استخدام Fast Message Queue مع واجهات AIDL باستخدام الخلفية في NDK. يتيح ذلك للعمليات التواصل بدون تكاليف إضافية والقيود المفروضة على معاملات الربط بعد بعض الإعدادات القصيرة. يتيح استخدام Stable AIDL التواصل بين عمليات النظام و المورّد.

أنواع الحمولات المسموح بها

يجب أن تتضمّن الرسائل المُرسَلة بين العمليات في قائمة انتظار رسائل الذاكرة المشتركة تنسيق الذاكرة نفسه على مستوى حدود العمليات، ولا يمكن أن تحتوي على مؤشرات. سيؤدي محاولة إنشاء AidlMessageQueue بنوع غير متوافق إلى حدوث خطأ في الترجمة.

أنواع الطوابير المتوافقة

تتوفّر أنواع الطوابير نفسها من HIDL، والتي يُشار إليها غالبًا باسم "النكهات"، مع AIDL. وتُستخدَم هذه الوسائط كوسائط نماذج ل القوائم والأوصاف.

أنواع HIDL أنواع لغة تعريف واجهة نظام Android
android::hardware::kSynchronizedReadWrite android.hardware.common.fmq.SynchronizedReadWrite
android::hardware::kUnsynchronizedWrite android.hardware.common.fmq.UnsynchronizedWrite

كيفية الاستخدام

حدِّد واجهة AIDL التي ستُرسل MQDescriptor إلى العملية الأخرى. يمكن استخدام MQDescriptor في أي مكان يمكن فيه استخدام قطعة أرض.

وسيطات النموذج المطلوبة لدالة 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 بعد الإعداد هو نفسه استخدام HIDL MessageQueue. جميع واجهات برمجة التطبيقات الموضّحة في مقالة استخدام MessageQueue تتوفّر بالكامل مع AidlMessageQueue باستثناء واحد:

يتم استبدال const MQDescriptor<T, flavor>* getDesc() بـ MQDescriptor<T, U> dupeDesc() الذي يعرض MQDescriptor AIDL.