A partire da Android 12, la coda di messaggi rapidi può essere utilizzata con le interfacce AIDL mediante il backend NDK. In questo modo, i processi possono comunicare senza il sovraccarico e le limitazioni delle transazioni dei binder dopo una breve configurazione. L'utilizzo di Stable AIDL consente la comunicazione tra i processi del sistema e del fornitore.
Tipi di payload supportati
- Tipi
parcelable
AIDL @FixedSize - Tipi di
enum
AIDL - Tipi integrali AIDL
I messaggi inviati tra i processi nella coda di messaggi della memoria condivisa devono avere lo stesso
layout della memoria oltre i confini del processo e non può contenere puntatori. Il tentativo di creare un
AidlMessageQueue
con un tipo non supportato causerà un errore di compilazione.
Tipi di coda supportati
Gli stessi tipi di coda di HIDL, spesso chiamati varianti, sono supportati con AIDL. Queste vengono usate come argomenti del modello per le code e i descrittori.
Tipi di HIDL | Tipi AIDL |
---|---|
android::hardware::kSynchronizedReadWrite |
android.hardware.common.fmq.SynchronizedReadWrite |
android::hardware::kUnsynchronizedWrite |
android.hardware.common.fmq.UnsynchronizedWrite |
Modalità di utilizzo
Definisci l'interfaccia AIDL che trasmette MQDescriptor
all'altro processo.
MQDescriptor
può essere utilizzato ovunque possa essere un pacchetto.
Gli argomenti del modello obbligatori per MQDescriptor
sono il tipo di payload e il tipo di coda.
import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite
void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);
Il processo di configurazione di ciascun lato della coda di messaggi è quasi identico a il processo con l'HIDL, usando solo i tipi 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);
Il processo di ricezione creerà l'altro lato della coda con il descrittore ricevuto dall'interfaccia 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()) {
...
}
L'utilizzo di AidlMessageQueue
dopo la configurazione è lo stesso del dispositivo HIDL MessageQueue
.
Tutte le API descritte in Utilizzo di MessageQueue
sono completamente supportate con AidlMessageQueue
, ad eccezione di una:
const MQDescriptor<T, flavor>* getDesc()
viene sostituito da MQDescriptor<T, U> dupeDesc()
che restituisce l'AIDL MQDescriptor
.