ตั้งแต่ Android 12 เป็นต้นไป คุณจะใช้ Fast Message Queue กับอินเทอร์เฟซ AIDL โดยใช้แบ็กเอนด์ NDK ได้ ซึ่งช่วยให้กระบวนการต่างๆ สื่อสารกันได้โดยไม่มีค่าใช้จ่ายและข้อจำกัดของธุรกรรม Binder หลังจาก การตั้งค่าสั้นๆ การใช้ AIDL ที่เสถียรช่วยให้การสื่อสารระหว่างระบบและ กระบวนการของผู้ให้บริการเป็นไปได้
ประเภทเพย์โหลดที่รองรับ
FixedSizeประเภท AIDLparcelable(ไม่พร้อมใช้งานจากแบ็กเอนด์cpp)- ประเภท AIDL
union(ใช้ไม่ได้จากแบ็กเอนด์cpp) - ประเภท
enumAIDL - ประเภทจำนวนเต็ม AIDL
ข้อความที่ส่งระหว่างกระบวนการในคิวข้อความของหน่วยความจำที่ใช้ร่วมกันต้องมีเลย์เอาต์หน่วยความจำเดียวกันในขอบเขตของกระบวนการ และต้องไม่มีพอยน์เตอร์ การพยายามสร้าง AidlMessageQueue ด้วยประเภทที่ไม่รองรับจะทำให้เกิดข้อผิดพลาดในการคอมไพล์ ใช้ประเภท AIDL parcelable และ union ในแบ็กเอนด์ cpp กับ Fast Message Queue ไม่ได้เนื่องจากประเภทเหล่านี้สืบทอดมาจาก 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
API ทั้งหมดที่อธิบายไว้ในใช้ MessageQueue ได้รับการรองรับอย่างเต็มรูปแบบ
ด้วย AidlMessageQueue ยกเว้นกรณีเดียว
const MQDescriptor<T, flavor>* getDesc() จะแทนที่ด้วย MQDescriptor<T, U> dupeDesc()
ซึ่งจะแสดงผล AIDL MQDescriptor