Ab Android 12 kann die Schnellnachrichtenwarteschlange mit AIDL-Schnittstellen über das NDK-Backend verwendet werden. So können Prozesse ohne den Aufwand und die Einschränkungen von Bindungstransaktionen zu kommunizieren, kurze Einrichtung. Die Verwendung von Stable AIDL ermöglicht die Kommunikation zwischen System und Zulieferunternehmen.
Unterstützte Nutzlasttypen
- @FixedSize AIDL-
parcelable
-Typen - AIDL-
enum
-Typen - Ganzzahlige AIDL-Typen
Die zwischen Prozessen in der geteilten Speichernachrichtenwarteschlange gesendeten Nachrichten müssen über Prozessgrenzen hinweg dasselbe Speicherlayout haben und dürfen keine Verweise enthalten. Der Versuch, eine AidlMessageQueue
mit einem nicht unterstützten Typ zu erstellen, führt zu einem Kompilierungsfehler.
Unterstützte Warteschlangentypen
Dieselben Warteschlangentypen aus HIDL, die oft als Varianten bezeichnet werden, werden auch von AIDL unterstützt. Sie werden als Vorlagenargumente für die Warteschlangen und Deskriptoren verwendet.
HIDL-Typen | AIDL-Typen |
---|---|
android::hardware::kSynchronizedReadWrite |
android.hardware.common.fmq.SynchronizedReadWrite |
android::hardware::kUnsynchronizedWrite |
android.hardware.common.fmq.UnsynchronizedWrite |
Verwendung
Definieren Sie die AIDL-Schnittstelle, über die die MQDescriptor
an den anderen Prozess übergeben wird.
MQDescriptor
kann überall dort verwendet werden, wo ein Parcelable verwendet werden kann.
Die erforderlichen Vorlagenargumente für MQDescriptor
sind „Nutzlasttyp“ und „Queue-Variante“.
import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite
void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);
Die Einrichtung der einzelnen Seiten der Nachrichtenwarteschlange ist fast identisch mit dem Prozess mit HIDL, nur dass hier die AIDL-Typen verwendet werden.
#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);
Der empfangende Prozess erstellt die andere Seite der Warteschlange mit dem Descriptor, der von der AIDL-Schnittstelle empfangen wurde.
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()) {
...
}
Die Verwendung von AidlMessageQueue
nach der Einrichtung entspricht der HIDL-MessageQueue
.
Alle unter Nachrichtenwarteschlange verwenden beschriebenen APIs
werden von AidlMessageQueue
mit einer Ausnahme vollständig unterstützt:
const MQDescriptor<T, flavor>* getDesc()
wird durch MQDescriptor<T, U> dupeDesc()
ersetzt
das die AIDL MQDescriptor
zurückgibt.