Esegui i servizi AIDL in modo dinamico

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 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 dell'app non sono supportati e devono usare invece servizi associati.

La chiusura dinamica 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à. Questo processo verrà quindi arrestato quando tutti i servizi sono inutilizzati.

Configurare un file init .rc 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:

  • interface aidl serviceName: consente a servicemanager di trovare il servizio. Se il servizio utilizza più interfacce, dichiara ciascuna interfaccia su una riga separata. Questi nomi devono essere esattamente quelli previsti da servicemanager e potrebbero 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 maggiori informazioni, consulta il file Leggimi di Android Init Language in AOSP.

Esempi:

Registra un servizio

Ogni servizio viene creato e registrato con servicemanager. La registrazione spesso viene eseguita in un file denominato main.cpp, ma l'implementazione può variare. Di solito la registrazione ha un aspetto simile al seguente:

using android::defaultServiceManager;

defaultServiceManager()->addService(serviceName, service);

La registrazione è talvolta astratta da BinderService::publish o BinderService::instantiate, che chiamano il codice riportato sopra.

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

Ottieni il servizio

Per recuperare un servizio lazy, è necessario avviarlo e recuperarlo. La chiamata a getService sul gestore del servizio avvia il servizio, ma in genere vuoi riceverlo non appena è disponibile e devi utilizzare waitForService varianti. Consulta la documentazione specifica per i backend per informazioni su come utilizzarli.

Rilascia il servizio

La chiusura dinamica si basa sul conteggio dei riferimenti, quindi i client non devono trattenere il servizio quando non è in uso.

Esempi:

Disattiva 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, deve essere chiamata prima del giorno registerService.

Esempio: apexservice