A partir do Android 12, o Fast Message Queue pode ser usado com interfaces AIDL usando o back-end do NDK. Isso permite que os processos se comuniquem sem a sobrecarga e as restrições das transações do fichário após uma breve configuração. O uso de AIDL estável permite a comunicação entre o sistema e os processos do fornecedor.
Tipos de carga suportados
- @FixedSize Tipos
parcelable
AIDL - Tipos de
enum
AIDL - Tipos integrais AIDL
As mensagens enviadas entre os processos na fila de mensagens da memória compartilhada devem ter o mesmo layout de memória entre os limites do processo e não podem conter ponteiros. Tentar criar um AidlMessageQueue
com um tipo que não é compatível causará um erro de compilação.
Tipos de fila suportados
Os mesmos tipos de fila do HIDL, geralmente chamados de tipos, são suportados com o AIDL. Eles são usados como argumentos de modelo para as filas e descritores.
Tipos HIDL | Tipos de AIDL |
---|---|
android::hardware::kSynchronizedReadWrite | android.hardware.common.fmq.SynchronizedReadWrite |
android::hardware::kUnsynchronizedWrite | android.hardware.common.fmq.UnsynchronizedWrite |
Como usar
Defina a interface AIDL que passará o MQDescriptor
para o outro processo. MQDescriptor
pode ser usado em qualquer lugar que um parcelable possa estar.
Os argumentos de modelo necessários para MQDescriptor
são tipo de carga útil e tipo de fila.
import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite
void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);
O processo de configurar cada lado da fila de mensagens é quase idêntico ao processo usando HIDL , apenas usando os 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);
O processo receptor criará o outro lado da fila com o descritor recebido da interface 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 o AidlMessageQueue
após a configuração é o mesmo que o HIDL MessageQueue
. Todas as APIs descritas em Usando o MessageQueue são totalmente suportadas com AidlMessageQueue
com uma exceção:
const MQDescriptor<T, flavor>* getDesc()
é substituído por MQDescriptor<T, U> dupeDesc()
que retorna o AIDL MQDescriptor
.