A partir de Android 12, Fast Message Queue se puede utilizar con interfaces AIDL utilizando el backend NDK. Esto permite que los procesos se comuniquen sin los gastos generales y las restricciones de las transacciones vinculantes después de una breve configuración. El uso de Stable AIDL permite la comunicación entre el sistema y los procesos del proveedor.
Tipos de carga soportados
- @FixedSize Tipos
parcelable
AIDL - Tipos
enum
AIDL - Tipos integrales AIDL
Los mensajes enviados entre procesos en la cola de mensajes de memoria compartida deben tener el mismo diseño de memoria en todos los límites del proceso y no pueden contener punteros. Intentar crear un AidlMessageQueue
con un tipo que no es compatible provocará un error de compilación.
Tipos de cola admitidos
Los mismos tipos de colas de HIDL, a menudo llamados tipos, son compatibles con AIDL. Estos se utilizan como argumentos de plantilla para las colas y los descriptores.
Tipos de HIDL | Tipos de AIDL |
---|---|
android::hardware::kSynchronizedReadWrite | android.hardware.common.fmq.SynchronizedReadWrite |
android::hardware::kUnsynchronizedWrite | android.hardware.common.fmq.UnsynchronizedWrite |
Cómo utilizar
Defina la interfaz AIDL que pasará el MQDescriptor
al otro proceso. MQDescriptor
se puede utilizar en cualquier lugar donde se pueda ubicar un paquete.
Los argumentos de plantilla necesarios para MQDescriptor
son el tipo de carga útil y el tipo de cola.
import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite
void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);
El proceso de configuración de cada lado de la cola de mensajes es casi idéntico al proceso que usa HIDL , solo que usa los tipos 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);
El proceso de recepción creará el otro lado de la cola con el descriptor recibido desde la interfaz 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()) {
...
}
Usar AidlMessageQueue
después de la configuración es lo mismo que HIDL MessageQueue
. Todas las API descritas en Uso de MessageQueue son totalmente compatibles con AidlMessageQueue
con una excepción:
const MQDescriptor<T, flavor>* getDesc()
se reemplaza por MQDescriptor<T, U> dupeDesc()
que devuelve el AIDL MQDescriptor
.