A partire da Android 12, Fast Message Queue può essere utilizzato con le interfacce AIDL utilizzando il backend NDK. Ciò consente ai processi di comunicare senza l'overhead e le limitazioni delle transazioni binder dopo una breve configurazione. L'utilizzo di AIDL stabile consente la comunicazione tra il sistema e i processi del fornitore.
Tipi di payload supportati
- Tipi
parcelableAIDL @FixedSize - Tipi
enumAIDL - Tipi integrali AIDL
I messaggi inviati tra processi nella coda di messaggi della memoria condivisa devono avere lo stesso
layout di memoria tra i limiti dei processi e non possono contenere puntatori. Il tentativo di creare un
AidlMessageQueue con un tipo non supportato causerà un errore di compilazione.
Tipi di code supportati
Con AIDL sono supportati gli stessi tipi di coda di HIDL, spesso chiamati varianti. Questi vengono utilizzati come argomenti del modello per le code e i descrittori.
| Tipi HIDL | Tipi di 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 trasmetterà MQDescriptor all'altro processo.
MQDescriptor può essere utilizzato ovunque sia possibile utilizzare un oggetto Parcelable.
Gli argomenti del modello richiesti 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);
La procedura di configurazione di ogni lato della coda di messaggi è quasi identica a quella che utilizza HIDL, ma con 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 è uguale a quello di MessageQueue HIDL.
Tutte le API descritte in Utilizzo di MessageQueue
sono completamente supportate con AidlMessageQueue, con una sola eccezione:
const MQDescriptor<T, flavor>* getDesc() viene sostituito da MQDescriptor<T, U> dupeDesc()
che restituisce l'AIDL MQDescriptor.