自 2025 年 3 月 27 日起,我們建議您使用 android-latest-release
而非 aosp-main
建構及貢獻 AOSP。詳情請參閱「Android 開放原始碼計畫變更」。
使用 AIDL 建立快速訊息佇列
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
自 Android 12 起,快速訊息佇列可搭配使用 NDK 後端的 AIDL 介面。這樣一來,在經過短暫設定後,程序就能進行通訊,而不會受到繫結器交易的額外負擔和限制。使用穩定版 AIDL 可讓系統與供應商程序之間進行通訊。
支援的酬載類型
在共用記憶體訊息佇列中,程序之間傳送的訊息必須在程序邊界具有相同的記憶體版面配置,且不得包含指標。如果嘗試使用不支援的類型建立 AidlMessageQueue
,就會導致編譯錯誤。
支援的佇列類型
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
的情況與 HIDL MessageQueue
相同。使用 MessageQueue 一文中所述的所有 API 都完全支援 AidlMessageQueue
,但有一個例外:
const MQDescriptor<T, flavor>* getDesc()
已由 MQDescriptor<T, U> dupeDesc()
取代,後者會傳回 AIDL MQDescriptor
。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-07-27 (世界標準時間)。
[[["容易理解","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 (世界標準時間)。"],[],[],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`."]]