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 |
使用方法
MQDescriptor
を他のプロセスに渡す AIDL インターフェースを定義します。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
で完全にサポートされますが、下記の例外が 1 つあります。
const MQDescriptor<T, flavor>* getDesc()
は、AIDL MQDescriptor
を返す MQDescriptor<T, U> dupeDesc()
に置き換えられます。