A partire da Android 11, i servizi AIDL nativi in esecuzione nella partizione di sistema possono essere avviati e arrestati dinamicamente in base alle esigenze. I servizi dinamici vengono avviati la prima volta che vengono richiesti e si arrestano automaticamente quando non sono più in uso.
Servizi che possono essere eseguiti in modo dinamico
Questa funzionalità è disponibile solo per i servizi nativi il cui ciclo di vita può essere controllato da init
e servicemanager
. I servizi all'interno dei pacchetti di app non sono supportati e devono utilizzare servizi associati.
L'arresto dinamico funziona arrestando il processo in cui viene eseguito il servizio. Se nello stesso processo esistono più servizi, tutti devono essere registrati come dinamici per essere compatibili con questa funzionalità. Il processo verrà quindi interrotto quando tutti i servizi non saranno in uso.
Configurare il file .rc di inizializzazione di un servizio
Per eseguire un servizio in modo dinamico, aggiungi le seguenti opzioni al file init.rc
del servizio dopo la riga service <name> <cmd>
iniziale.
interface aidl serviceName
disabled
oneshot
Queste opzioni consentono di:
interface aidl serviceName
: consente aservicemanager
di trovare il servizio. Se il servizio utilizza più interfacce, dichiara ogni interfaccia su una propria riga. Questi nomi devono essere esattamente quelli previsti daservicemanager
e possono essere diversi dal nome del processo.disabled
: impedisce l'avvio automatico del servizio all'avvio.oneshot
: impedisce il riavvio automatico del servizio ogni volta che viene interrotto.
Per ulteriori informazioni, consulta il file Readme Lingua di inizializzazione Android in AOSP.
Esempi:
Registra un servizio
Ogni servizio viene creato e registrato in servicemanager
. La registrazione spesso
viene eseguita in un file denominato main.cpp
, ma l'implementazione può variare. In genere, la registrazione ha il seguente aspetto:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
La registrazione viene talvolta trattata in modo astratto da BinderService::publish
o
BinderService::instantiate
, che richiamano il codice riportato sopra.
Per registrare un servizio come dinamico, sostituisci il relativo codice di registrazione con quanto segue:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager
comunica con LazyServiceRegistrar
per arrestare i servizi in base ai conteggi dei riferimenti.
Esempi:
Configura i client di servizio AIDL
Ottieni il servizio
Per recuperare un servizio lazy, è necessario avviarlo e recuperarlo.
La chiamata a getService
nel gestore del servizio avvia il servizio, ma in genere,
si vuole ottenere il servizio non appena è disponibile e devono essere utilizzate le varianti di waitForService
. Consulta la documentazione specifica per i backend per informazioni su come utilizzarli.
Rilasciare il servizio
L'arresto dinamico si basa sul conteggio dei riferimenti, pertanto i client non devono trattenere il servizio quando non è in uso.
Esempi:
Disattivare temporaneamente l'arresto
Se vuoi che un servizio venga eseguito in modo indipendente fino al completamento di alcune attività e poi passi al comportamento dinamico, puoi utilizzare LazyServiceRegistrar::forcePersist
per attivare e disattivare l'arresto dinamico. Se questa chiamata viene effettuata dal lato server, la chiamata deve essere eseguita prima del giorno registerService
.
Esempio: apexservice