Esecuzione dinamica dei servizi AIDL

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 vengono più utilizzati.

Servizi che possono essere eseguiti dinamicamente

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 invece 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à. Tale processo verrà quindi interrotto quando tutti i servizi saranno inutilizzati.

Configurazione del file init .rc di un servizio

Per eseguire un servizio in modo dinamico, aggiungere le seguenti opzioni al file init .rc del servizio dopo la riga iniziale service <name> <cmd> .

interface aidl serviceName
disabled
oneshot

Queste opzioni effettuano le seguenti operazioni:

  • interface aidl serviceName : consente servicemanager di trovare il servizio. Se il servizio utilizza più interfacce, dichiara ciascuna interfaccia sulla propria riga. Questi nomi devono essere esattamente quelli previsti servicemanager e potrebbero differire dal nome del processo.
  • disabled : impedisce al servizio di avviarsi automaticamente all'avvio.
  • oneshot : impedisce al servizio di riavviarsi automaticamente ogni volta che viene interrotto.

Per ulteriori informazioni, vedere il file Leggimi della lingua Android Init in AOSP.

Esempi:

Registrazione di un servizio

Ogni servizio viene creato e registrato con servicemanager . La registrazione avviene spesso in un file denominato main.cpp , ma l'implementazione può variare. La registrazione di solito è simile a questa:

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, sostituire il suo 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:

Configurazione dei client del servizio AIDL

Ottenere il servizio

Per recuperare un servizio lazy, il servizio deve essere avviato e quindi recuperato. Chiamando getService sul gestore del servizio verrà avviato il servizio, ma di solito si desidera ottenere il servizio non appena è disponibile e dovrebbero essere utilizzate le varianti waitForService . Consulta la documentazione specifica del backend su come utilizzarli.

Rilascio del servizio

L'arresto dinamico si basa sul conteggio dei riferimenti, pertanto i client non devono trattenere il servizio quando non è in uso.

Esempi:

Disattivazione temporanea dello spegnimento

Se desideri 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, dovrebbe essere chiamato prima di registerService .

Esempio: apexservice