ตั้งแต่วันที่ 27 มีนาคม 2025 เป็นต้นไป เราขอแนะนำให้ใช้ android-latest-release
แทน aosp-main
เพื่อสร้างและมีส่วนร่วมใน AOSP โปรดดูข้อมูลเพิ่มเติมที่หัวข้อการเปลี่ยนแปลงใน AOSP
รอส่งข้อความได้เร็วขึ้นด้วย AIDL
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
ตั้งแต่ Android 12 เป็นต้นไป คิวข้อความที่รวดเร็วสามารถใช้กับอินเทอร์เฟซ AIDL โดยใช้แบ็กเอนด์ NDK ซึ่งช่วยให้กระบวนการสื่อสารกันได้โดยไม่เกิดค่าใช้จ่ายเพิ่มเติมและข้อจํากัดของธุรกรรม Binder หลังจากการตั้งค่าสั้นๆ การใช้ AIDL ที่เสถียรช่วยให้ระบบสื่อสารกับกระบวนการของผู้ให้บริการได้
ประเภทเพย์โหลดที่รองรับ
ข้อความที่ส่งระหว่างกระบวนการในคิวข้อความหน่วยความจำที่ใช้ร่วมกันต้องมีเลย์เอาต์หน่วยความจำเดียวกันในขอบเขตกระบวนการและไม่มีพอยน์เตอร์ การพยายามสร้าง AidlMessageQueue
ที่มีประเภทที่ไม่รองรับจะทำให้เกิดข้อผิดพลาดในการคอมไพล์
ประเภทคิวที่รองรับ
AIDL รองรับประเภทคิวเดียวกันจาก HIDL ซึ่งมักเรียกว่า "Flavour" ซึ่งจะใช้เป็นอาร์กิวเมนต์ของเทมเพลตสำหรับคิวและตัวระบุ
ประเภท 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
หลังจากการตั้งค่าจะเหมือนกับ HIDL MessageQueue
AidlMessageQueue
รองรับ API ทั้งหมดที่อธิบายไว้ในการใช้ MessageQueue โดยมีข้อยกเว้นเพียงอย่างเดียวดังนี้
const MQDescriptor<T, flavor>* getDesc()
แทนที่ด้วย MQDescriptor<T, U> dupeDesc()
ซึ่งแสดงผล AIDL MQDescriptor
ตัวอย่างเนื้อหาและโค้ดในหน้าเว็บนี้ขึ้นอยู่กับใบอนุญาตที่อธิบายไว้ในใบอนุญาตการใช้เนื้อหา Java และ OpenJDK เป็นเครื่องหมายการค้าหรือเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-07-27 UTC
[[["เข้าใจง่าย","easyToUnderstand","thumb-up"],["แก้ปัญหาของฉันได้","solvedMyProblem","thumb-up"],["อื่นๆ","otherUp","thumb-up"]],[["ไม่มีข้อมูลที่ฉันต้องการ","missingTheInformationINeed","thumb-down"],["ซับซ้อนเกินไป/มีหลายขั้นตอนมากเกินไป","tooComplicatedTooManySteps","thumb-down"],["ล้าสมัย","outOfDate","thumb-down"],["ปัญหาเกี่ยวกับการแปล","translationIssue","thumb-down"],["ตัวอย่าง/ปัญหาเกี่ยวกับโค้ด","samplesCodeIssue","thumb-down"],["อื่นๆ","otherDown","thumb-down"]],["อัปเดตล่าสุด 2025-07-27 UTC"],[],[],null,["# Fast Message Queue with AIDL\n\nAs of Android 12, [Fast Message Queue](/docs/core/architecture/hidl/fmq) can be\nused with AIDL interfaces using the NDK backend. This allows processes to\ncommunicate without the overhead and restrictions of binder transactions after\nsome short setup. Using [Stable AIDL](/docs/core/architecture/aidl/stable-aidl) allows communication between system and\nvendor processes.\n\nSupported payload types\n-----------------------\n\n- [@FixedSize](/docs/core/architecture/aidl/aidl-annotations#fixedsize) AIDL `parcelable` types\n- AIDL `enum` types\n- [AIDL integral types](/docs/core/architecture/aidl/aidl-backends#types)\n\nThe messages sent between processes in the shared memory message queue must have the same\nmemory layout across process boundaries and cannot contain pointers. Attempting to create an\n`AidlMessageQueue` with a type that isn't supported will cause a compilation error.\n\nSupported queue types\n---------------------\n\nThe same [queue types](/docs/core/architecture/hidl/fmq#flavors) from HIDL, often\ncalled flavors, are supported with AIDL. These are used as template arguments for\nthe queues and descriptors.\n\n| HIDL Types | AIDL Types |\n|---------------------------------------------|-----------------------------------------------------|\n| `android::hardware::kSynchronizedReadWrite` | `android.hardware.common.fmq.SynchronizedReadWrite` |\n| `android::hardware::kUnsynchronizedWrite` | `android.hardware.common.fmq.UnsynchronizedWrite` |\n\nHow to use\n----------\n\nDefine the AIDL interface that will pass the `MQDescriptor` to the other process.\n`MQDescriptor` can be used anywhere a parcelable can be.\n\nThe required template arguments for `MQDescriptor` are payload type and queue flavor. \n\n import android.hardware.common.fmq.MQDescriptor\n import android.hardware.common.fmq.SynchronizedReadWrite\n\n void getQueue(out MQDescriptor\u003cint, SynchronizedReadWrite\u003e mqDesc);\n\nThe process of setting up each side of the message queue is nearly identical to\nthe [process using HIDL](/docs/core/architecture/hidl/fmq#setup), just using the AIDL types. \n\n #include \u003cfmq/AidlMessageQueue.h\u003e\n ...\n using ::android::AidlMessageQueue;\n using ::aidl::android::hardware::common::fmq::MQDescriptor;\n using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;\n ...\n ndk::ScopedAStatus MyInterface::getQueue(MQDescriptor\u003cint32_t, SynchronizedReadWrite\u003e* mqDesc) {\n *mqDesc = mFmqSynchronized-\u003edupeDesc();\n return ndk::ScopedAStatus::ok();\n }\n ...\n // Create the first side of the queue before servicing getQueue() in this example\n mFmqSynchronized =\n new AidlMessageQueue\u003cint32_t, SynchronizedReadWrite\u003e(kNumElementsInQueue);\n\nThe receiving process will create the other side of the queue with the descriptor received from the AIDL interface. \n\n MQDescriptor\u003cint32_t, SynchronizedReadWrite\u003e desc;\n auto ret = service-\u003egetQueue(true, &desc);\n if (!ret.isOk()) {\n ...\n }\n // By default the constructor will reset the read and write pointers of the queue.\n // Add a second `false` argument to avoid resetting the pointers.\n mQueue = new (std::nothrow) AidlMessageQueue\u003cint32_t, SynchronizedReadWrite\u003e(desc);\n if (!mQueue-\u003eisValid()) {\n ...\n }\n\nUsing the `AidlMessageQueue` after setup is the same as the HIDL `MessageQueue`.\nAll of the APIs described at [Using the MessageQueue](/docs/core/architecture/hidl/fmq#using)\nare fully supported with `AidlMessageQueue` with one exception:\n\n`const MQDescriptor\u003cT, flavor\u003e* getDesc()` is replaced by `MQDescriptor\u003cT, U\u003e dupeDesc()`\nwhich returns the AIDL `MQDescriptor`."]]