Depuis Android 12, la Fast Message Queue peut être utilisée avec les interfaces AIDL à l'aide du backend NDK. Cela permet aux processus de communiquer sans les frais généraux ni les restrictions des transactions Binder après une courte configuration. L'utilisation d'AIDL stable permet la communication entre les processus système et fournisseur.
Types de charge utile acceptés
- Types
parcelable
AIDL @FixedSize - Types
enum
AIDL - Types intégraux AIDL
Les messages envoyés entre les processus dans la file d'attente de messages en mémoire partagée doivent avoir la même disposition de mémoire au-delà des limites des processus et ne peuvent pas contenir de pointeurs. Toute tentative de création d'un AidlMessageQueue
avec un type non compatible entraînera une erreur de compilation.
Types de files d'attente compatibles
Les mêmes types de files d'attente que HIDL, souvent appelés "saveurs", sont compatibles avec AIDL. Ils sont utilisés comme arguments de modèle pour les files d'attente et les descripteurs.
Types HIDL | Types AIDL |
---|---|
android::hardware::kSynchronizedReadWrite |
android.hardware.common.fmq.SynchronizedReadWrite |
android::hardware::kUnsynchronizedWrite |
android.hardware.common.fmq.UnsynchronizedWrite |
Utilisation
Définissez l'interface AIDL qui transmettra MQDescriptor
à l'autre processus.
MQDescriptor
peut être utilisé partout où un élément Parcelable peut l'être.
Les arguments de modèle requis pour MQDescriptor
sont le type de charge utile et le type de file d'attente.
import android.hardware.common.fmq.MQDescriptor
import android.hardware.common.fmq.SynchronizedReadWrite
void getQueue(out MQDescriptor<int, SynchronizedReadWrite> mqDesc);
La procédure de configuration de chaque côté de la file d'attente de messages est presque identique à la procédure utilisant HIDL, mais avec les types 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);
Le processus de réception créera l'autre côté de la file d'attente avec le descripteur reçu de l'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()) {
...
}
L'utilisation de AidlMessageQueue
après la configuration est la même que pour le HIDL MessageQueue
.
Toutes les API décrites dans Utiliser MessageQueue sont entièrement compatibles avec AidlMessageQueue
, à une exception près :
const MQDescriptor<T, flavor>* getDesc()
est remplacé par MQDescriptor<T, U> dupeDesc()
, qui renvoie l'MQDescriptor
AIDL.