À partir d'Android 11, les services AIDL natifs s'exécutant dans la partition système peut être démarrée et arrêtée de manière dynamique en fonction des besoins. Les services dynamiques démarrent à leur première demande et s'arrêtent automatiquement elles ne sont plus utilisées.
Services pouvant s'exécuter de manière dynamique
Cette fonctionnalité n'est disponible que pour les services natifs dont le cycle de vie peut être
contrôlé par init
et servicemanager
. Les services des packages d'application ne sont pas compatibles et doivent utiliser des services liés à la place.
L'arrêt dynamique consiste à arrêter le processus dans lequel le service s'exécute. Si plusieurs services existent dans le même processus, ils doivent tous être enregistrés en tant que dynamiques pour être compatibles avec cette fonctionnalité. Ce processus s'arrête ensuite lorsque tous les services sont inutilisés.
Configurer le fichier init .rc d'un service
Pour exécuter un service de manière dynamique, ajoutez les options suivantes à la commande init du service
.rc
après la ligne service <name> <cmd>
initiale.
interface aidl serviceName
disabled
oneshot
Ces options permettent d'effectuer les opérations suivantes:
interface aidl serviceName
: autoriseservicemanager
à trouver le service. Si le service utilise plusieurs interfaces, déclarez chacune d'elles séparément. ligne. Ces noms doivent correspondre exactement à ce queservicemanager
attend et peuvent différer du nom du processus.disabled
: empêche le service de démarrer automatiquement au démarrage.oneshot
: empêche le service de redémarrer automatiquement à chaque fois qu'il est arrêté.
Pour en savoir plus, consultez le Readme du langage Android Init dans AOSP.
Exemples :
Enregistrer un service
Chaque service est créé et enregistré auprès de servicemanager
. Inscription fréquente
se trouve dans un fichier nommé main.cpp
, mais l'implémentation peut varier. La
l'inscription ressemble généralement à ceci:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
L'enregistrement est parfois suspendu par BinderService::publish
ou
BinderService::instantiate
, qui appellent le code ci-dessus.
Pour enregistrer un service en tant que service dynamique, remplacez son code d'enregistrement par le code suivant :
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager
communique avec LazyServiceRegistrar
pour arrêter les services en fonction de leur nombre de références.
Exemples :
Configurer les clients de service AIDL
Obtenir le service
Pour récupérer un service paresseux, vous devez d'abord le démarrer, puis le récupérer.
L'appel de getService
sur le gestionnaire de services démarre le service, mais généralement, vous souhaitez obtenir le service dès qu'il est disponible, et les variantes waitForService
doivent être utilisées. Pour en savoir plus sur leur utilisation, consultez la documentation spécifique au backend.
Libérer le service
L'arrêt dynamique est basé sur le comptage des références. Par conséquent, les clients ne doivent pas conserver le service lorsqu'il n'est pas utilisé.
Exemples :
Désactiver temporairement l'arrêt
Si vous souhaitez qu'un service s'exécute indépendamment jusqu'à ce que certaines tâches soient terminées, puis qu'il passe à un comportement dynamique, vous pouvez utiliser LazyServiceRegistrar::forcePersist
pour activer et désactiver l'arrêt dynamique. S'il est appelé côté serveur, il doit être appelé avant registerService
.
Exemple : apexservice