AIDL-Dienste dynamisch ausführen

Ab Android 11 können native AIDL-Dienste, die in der Systempartition ausgeführt werden, bei Bedarf dynamisch gestartet und gestoppt werden. Dynamische Dienste starten, wenn sie zum ersten Mal angefordert werden, und stoppen automatisch, wenn sie nicht mehr verwendet werden.

Dienste, die dynamisch ausgeführt werden können

Diese Funktion ist nur für native Dienste verfügbar, deren Lebenszyklen von init und servicemanager gesteuert werden können. Dienste innerhalb von App-Paketen werden nicht unterstützt und sollten stattdessen gebundene Dienste verwenden.

Beim dynamischen Herunterfahren wird der Prozess heruntergefahren, in dem der Dienst ausgeführt wird. Wenn im selben Prozess mehrere Dienste vorhanden sind, müssen alle als dynamisch registriert werden, um mit dieser Funktion kompatibel zu sein. Dieser Prozess wird dann beendet, wenn alle Dienste nicht verwendet werden.

Konfigurieren der Init-RC-Datei eines Dienstes

Um einen Dienst dynamisch auszuführen, fügen Sie die folgenden Optionen zur Init .rc Datei des Dienstes nach der führenden Zeile service <name> <cmd> hinzu.

interface aidl serviceName
disabled
oneshot

Diese Optionen bewirken Folgendes:

  • interface aidl serviceName : Ermöglicht servicemanager , den Dienst zu finden. Wenn der Dienst mehrere Schnittstellen verwendet, deklarieren Sie jede Schnittstelle in einer eigenen Zeile. Diese Namen müssen genau den Erwartungen servicemanager entsprechen und können vom Prozessnamen abweichen.
  • disabled : Verhindert, dass der Dienst beim Booten automatisch gestartet wird.
  • oneshot : Verhindert, dass der Dienst bei jedem Stopp automatisch neu gestartet wird.

Weitere Informationen finden Sie in der Android Init Language Readme in AOSP.

Beispiele:

Registrieren eines Dienstes

Jeder Dienst wird bei servicemanager erstellt und registriert. Die Registrierung erfolgt häufig in einer Datei mit dem Namen main.cpp , die Implementierung kann jedoch variieren. Die Anmeldung sieht in der Regel etwa so aus:

using android::defaultServiceManager;

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

Die Registrierung wird manchmal durch BinderService::publish oder BinderService::instantiate abstrahiert, die den obigen Code aufrufen.

Um einen Dienst als dynamisch zu registrieren, ersetzen Sie seinen Registrierungscode durch Folgendes:

#include <binder/LazyServiceRegistrar.h>

using android::binder::LazyServiceRegistrar;

auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);

servicemanager kommuniziert mit LazyServiceRegistrar , um Dienste basierend auf ihrer Referenzanzahl herunterzufahren.

Beispiele:

Konfigurieren von AIDL-Dienstclients

Den Dienst erhalten

Um einen Lazy-Dienst abzurufen, muss der Dienst gestartet und dann abgerufen werden. Durch den Aufruf von getService im Dienstmanager wird der Dienst gestartet. Normalerweise möchten Sie den Dienst jedoch abrufen, sobald er verfügbar ist, und es sollten Varianten waitForService verwendet werden. Informationen zur Verwendung finden Sie in der Backend-spezifischen Dokumentation .

Freigabe des Dienstes

Das dynamische Herunterfahren basiert auf der Referenzzählung, sodass Clients den Dienst nicht behalten dürfen, wenn er nicht verwendet wird.

Beispiele:

Das Herunterfahren wird vorübergehend deaktiviert

Wenn Sie möchten, dass ein Dienst unabhängig ausgeführt wird, bis bestimmte Aufgaben abgeschlossen sind, und dann zu dynamischem Verhalten wechseln, können Sie LazyServiceRegistrar::forcePersist verwenden, um das dynamische Herunterfahren ein- und auszuschalten. Wenn dies von der Serverseite aufgerufen wird, sollte es vor registerService aufgerufen werden.

Beispiel: Apexservice