Esegui i servizi AIDL in modo dinamico

A partire da Android 11, i servizi AIDL nativi in esecuzione la partizione di sistema può essere avviata e arrestata in modo dinamico 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 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 all'init del servizio .rc dopo la riga service <name> <cmd> iniziale.

interface aidl serviceName
disabled
oneshot

Queste opzioni consentono di:

  • interface aidl serviceName: consente a servicemanager di trovare il servizio. Se il servizio utilizza più interfacce, dichiara ciascuna interfaccia separatamente dalla riga di comando. Questi nomi devono essere esattamente quelli previsti da servicemanager e potrebbero dal nome del processo.
  • disabled: impedisce l'avvio automatico del servizio all'avvio.
  • oneshot: impedisce il riavvio automatico del servizio a ogni avvio 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 avviene spesso 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 è 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 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 relativi conteggi di riferimento.

Esempi:

Configura i client di servizio AIDL

Ricevere il servizio

Per recuperare un servizio lazy, il servizio deve essere avviato e poi recuperato. La chiamata a getService del gestore del servizio avvierà il servizio, ma in genere vuoi ottenere il servizio non appena è disponibile e waitForService utilizzare le varianti. Vedi le sezioni specifiche documentazione 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 determinate attività e poi passi a un comportamento dinamico, puoi utilizzare LazyServiceRegistrar::forcePersist per attivare e disattivare l'arresto dinamico. Se viene chiamato lato server, deve essere chiamato prima di registerService.

Esempio: apexservice