A partir de Android 12, la cola de mensajes rápidos se puede usar con interfaces AIDL mediante el backend del NDK. Esto permite que los procesos se comuniquen sin la sobrecarga y las restricciones de las transacciones de Binder después de una configuración breve. El uso del AIDL estable permite la comunicación entre los procesos del sistema y del proveedor.
Tipos de cargas útiles admitidos
- Tipos
parcelable
de AIDL @FixedSize - Tipos de
enum
de AIDL - Tipos de números enteros de AIDL
Los mensajes que se envían entre procesos en la cola de mensajes de memoria compartida deben tener el mismo diseño de memoria en los límites del proceso y no pueden contener punteros. Si intentas crear un AidlMessageQueue
con un tipo que no es compatible, se producirá un error de compilación.
Tipos de filas compatibles
Los mismos tipos de cola de HIDL, que a menudo se denominan variantes, son compatibles con AIDL. Estos se usan 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 |
How to use
Define la interfaz de AIDL que pasará el MQDescriptor
al otro proceso.
MQDescriptor
se puede usar en cualquier lugar donde se pueda usar un elemento parcelable.
Los argumentos de plantilla obligatorios 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 con HIDL, solo que se usan los tipos de 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 de 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()) {
...
}
El uso de AidlMessageQueue
después de la configuración es igual que el MessageQueue
de HIDL.
Todas las APIs que se describen en Cómo usar MessageQueue son totalmente compatibles con AidlMessageQueue
, con una excepción:
const MQDescriptor<T, flavor>* getDesc()
se reemplaza por MQDescriptor<T, U> dupeDesc()
, que muestra el MQDescriptor
de AIDL.