自 Android 12 起,快速訊息佇列可搭配使用 NDK 後端的 AIDL 介面。這樣一來,程序就能在經過短暫設定後進行通訊,不必負擔繫結器交易的額外負荷,也不會受到限制。使用穩定版 AIDL 可在系統和供應商程序之間進行通訊。
支援的酬載類型
- @FixedSize AIDL
parcelable
型別 - AIDL
enum
型別 - 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
。