A partir de Android 12, se puede usar la cola de mensajes rápidos que se usa con las interfaces de AIDL mediante el backend del NDK. Esto permite que los procesos sin la sobrecarga ni las restricciones de las transacciones de Binder después de una configuración breve. El uso del AIDL estable permite la comunicación entre el sistema y los procesos de los proveedores.
Tipos de cargas útiles compatibles
- Tipos
parcelable
de AIDL @FixedSize - Tipos
enum
del AIDL - Tipos de integrales de AIDL
Los mensajes enviados entre los procesos de la cola de mensajes de memoria compartida deben tener la misma
diseño de la memoria entre límites de procesos y no puede contener punteros. Si intentas crear un
AidlMessageQueue
con un tipo que no se admite causará un error de compilación.
Tipos de colas compatibles
Los mismos tipos de colas del HIDL, a menudo llamados sabores, son compatibles con el 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 del AIDL que pasará el MQDescriptor
al otro proceso.
MQDescriptor
se puede usar en cualquier lugar que pueda ser un parcelable.
Los argumentos de plantilla requeridos para MQDescriptor
son el tipo de carga útil y la variante de cola.
import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite
void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);
El proceso de configurar cada lado de la cola de mensajes es casi idéntico al el proceso con HIDL, solo con 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 receptor creará el otro lado de la cola con el descriptor recibido de la interfaz del 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 el MessageQueue
de HIDL.
Todas las APIs descritas en Cómo usar MessageQueue
son totalmente compatibles con AidlMessageQueue
, con una excepción:
Se reemplazó const MQDescriptor<T, flavor>* getDesc()
por MQDescriptor<T, U> dupeDesc()
que muestra el MQDescriptor
del AIDL.