In Android 11 e versioni successive, i servizi AIDL nativi in esecuzione nella partizione di sistema possono essere avviati e arrestati dinamicamente in base alle necessità. I servizi dinamici vengono avviati 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 i cui cicli di vita possono essere
controllati 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à 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 svolgono le seguenti funzioni:
interface aidl serviceName: consente aservicemanagerdi trovare il servizio. Se il servizio utilizza più interfacce, dichiara ciascuna interfaccia su una riga separata. Questi nomi devono corrispondere esattamente a quelli previsti daservicemanagere 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 è simile alla seguente:
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 relativo 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 arrestare i servizi in base ai conteggi dei 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 in genere
vuoi ottenere il servizio non appena è disponibile e devono essere utilizzate le varianti di 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 al 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