Hàng đợi tin nhắn nhanh với AIDL

Kể từ Android 12, Hàng đợi tin nhắn nhanh có thể được sử dụng với giao diện AIDL sử dụng chương trình phụ trợ NDK. Điều này cho phép các quy trình giao tiếp mà không cần chi phí chung và hạn chế giao dịch ràng buộc sau một số thiết lập ngắn. Sử dụng AIDL ổn định cho phép giao tiếp giữa các quy trình của hệ thống và nhà cung cấp.

Các loại tải trọng được hỗ trợ

Các tin nhắn được gửi giữa các tiến trình trong hàng đợi tin nhắn bộ nhớ dùng chung phải có cùng bố cục bộ nhớ trên các ranh giới tiến trình và không được chứa con trỏ. Việc cố gắng tạo AidlMessageQueue với loại không được hỗ trợ sẽ gây ra lỗi biên dịch.

Các loại hàng đợi được hỗ trợ

Các loại hàng đợi tương tự từ HIDL, thường được gọi là hương vị, được hỗ trợ với AIDL. Chúng được sử dụng làm đối số mẫu cho hàng đợi và bộ mô tả.

Các loại HIDL Các loại AIDL
android::hardware::kSynchronizedReadWrite android.hardware.common.fmq.SynchronizedReadWrite
android::hardware::kUnsynchronizedWrite android.hardware.common.fmq.UnsynchronizedWrite

Cách sử dụng

Xác định giao diện AIDL sẽ chuyển MQDescriptor sang quy trình khác. MQDescriptor có thể được sử dụng ở bất cứ nơi nào có thể gửi được.

Các đối số mẫu bắt buộc cho MQDescriptor là loại tải trọng và kiểu hàng đợi.

import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite

void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);

Quá trình thiết lập mỗi bên của hàng đợi tin nhắn gần giống với quá trình sử dụng HIDL , chỉ sử dụng các loại 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);

Quá trình nhận sẽ tạo phía bên kia của hàng đợi với bộ mô tả nhận được từ giao diện 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()) {
   ...
}

Sử dụng AidlMessageQueue sau khi thiết lập cũng giống như HIDL MessageQueue . Tất cả các API được mô tả tại Sử dụng MessageQueue đều được AidlMessageQueue hỗ trợ đầy đủ với một ngoại lệ:

const MQDescriptor<T, flavor>* getDesc() được thay thế bằng MQDescriptor<T, U> dupeDesc() trả về AIDL MQDescriptor .