Hàng đợi tin nhắn nhanh bằng AIDL

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

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

Các thông báo được gửi giữa các quy trình trong hàng đợi thông báo bộ nhớ dùng chung phải có cùng bố cục bộ nhớ trên các ranh giới quy trình và không được chứa con trỏ. Việc cố gắng tạo một AidlMessageQueue có 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ợ

AIDL hỗ trợ các loại hàng đợi tương tự trong HIDL (thường được gọi là các biến thể). Các đối tượng này được dùng làm đối số mẫu cho các hàng đợi và dữ liệu đặc 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 dùng

Xác định giao diện AIDL sẽ truyền MQDescriptor đến quy trình khác. Bạn có thể dùng MQDescriptor ở bất cứ nơi nào có thể dùng một đối tượng có thể phân chia.

Các đối số mẫu bắt buộc cho MQDescriptor là loại tải trọng và hương vị 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 từng phía của hàng đợi thông báo gần giống với quá trình sử dụng HIDL, chỉ cần 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);

Quy trình nhận sẽ tạo phía còn lại của hàng đợi bằng 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()) {
   ...
}

Việc sử dụng AidlMessageQueue sau khi thiết lập cũng giống như MessageQueue HIDL. Tất cả các API được mô tả trong phần Sử dụng MessageQueue đều được hỗ trợ đầy đủ bằng AidlMessageQueue, ngoại trừ một trường hợp:

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