A partire da Android 11, i servizi AIDL nativi in esecuzione nella partizione di sistema possono essere avviati e arrestati dinamicamente in base alle necessità. I servizi dinamici iniziano quando vengono richiesti per la prima volta e si interrompono 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
invece.
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 arrestato quando tutti i servizi non vengono utilizzati.
Configura il file .rc init 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 eseguono le seguenti operazioni:
interface aidl serviceName
: consente aservicemanager
di trovare il servizio. Se il servizio utilizza più interfacce, dichiara ogni interfaccia sulla propria riga. Questi nomi devono corrispondere esattamente a quelli previsti daservicemanager
e potrebbero differire 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 saperne di più, consulta il file Readme di Android Init Language in AOSP.
Esempi:
Registrare un servizio
Ogni servizio viene creato e registrato con servicemanager
. La registrazione spesso
avviene in un file denominato main.cpp
, ma l'implementazione può variare. La
registrazione in genere ha un aspetto simile a questo:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
La registrazione a volte viene astratta da BinderService::publish
o
BinderService::instantiate
, che chiamano il codice precedente.
Per registrare un servizio come dinamico, sostituisci il codice di registrazione con il seguente:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager
comunica con LazyServiceRegistrar
per disattivare i servizi in base al numero di riferimenti.
Esempi:
Configura i client di servizio AIDL
Recuperare il servizio
Per recuperare un servizio lazy, il servizio deve essere avviato e poi recuperato.
La chiamata di getService
sul gestore del servizio avvierà il servizio, ma di solito
vuoi ottenere il servizio non appena è disponibile e devono essere utilizzate le varianti waitForService
. Consulta la documentazione specifica
per il backend
su come utilizzarli.
Rilasciare il servizio
L'arresto dinamico si basa sul conteggio dei riferimenti, pertanto i client non devono mantenere 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 determinate attività e poi passi a un comportamento dinamico, puoi utilizzare LazyServiceRegistrar::forcePersist
per attivare e disattivare l'arresto dinamico. Se viene chiamato dal lato server, deve essere chiamato prima di registerService
.
Esempio: apexservice