À partir d'Android 11, les services AIDL natifs exécutés dans la partition système peuvent être démarrés et arrêtés dynamiquement selon leurs besoins. Les services dynamiques démarrent lorsqu'ils sont demandés pour la première fois et s'arrêtent automatiquement lorsqu'ils ne sont plus utilisés.
Services pouvant s'exécuter de manière dynamique
Cette fonctionnalité est disponible uniquement pour les services natifs dont les cycles de vie peuvent être contrôlés par init
et servicemanager
. Les services contenus dans les packages d'application ne sont pas pris en charge et doivent plutôt utiliser des services liés .
L'arrêt dynamique fonctionne en arrêtant le processus dans lequel le service s'exécute. Si plusieurs services existent dans le même processus, ils doivent tous être enregistrés comme dynamiques pour être compatibles avec cette fonctionnalité. Ce processus s'arrêtera ensuite lorsque tous les services seront inutilisés.
Configuration du fichier init .rc d'un service
Pour exécuter un service de manière dynamique, ajoutez les options suivantes au fichier init .rc
du service après la première ligne service <name> <cmd>
.
interface aidl serviceName
disabled
oneshot
Ces options effectuent les opérations suivantes :
-
interface aidl serviceName
: Permet àservicemanager
de trouver le service. Si le service utilise plusieurs interfaces, déclarez chaque interface sur sa propre 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 arrêt.
Pour plus d’informations, consultez le fichier Readme du langage d’initialisation Android dans AOSP.
Exemples:
Enregistrer un service
Chaque service est créé et enregistré auprès de servicemanager
. L'enregistrement s'effectue souvent dans un fichier nommé main.cpp
, mais l'implémentation peut varier. L'enregistrement ressemble généralement à ceci :
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
L'enregistrement est parfois résumé par BinderService::publish
ou BinderService::instantiate
, qui appellent le code ci-dessus.
Pour enregistrer un service comme dynamique, remplacez son code d'enregistrement par ce qui suit :
#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:
Configuration des clients du service AIDL
Obtenir le service
Pour récupérer un service paresseux, le service doit être démarré puis récupéré. L'appel de getService
sur le gestionnaire de services démarrera 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. Consultez la documentation spécifique au backend pour savoir comment les utiliser.
Libération du service
L'arrêt dynamique est basé sur le comptage de références, les clients ne doivent donc 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 passe à un comportement dynamique, vous pouvez utiliser LazyServiceRegistrar::forcePersist
pour activer et désactiver l'arrêt dynamique. Si ceci est appelé côté serveur, il doit être appelé avant registerService
.
Exemple : serviceapex