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 beendet werden. Dynamische Dienste werden gestartet, wenn sie zum ersten Mal angefordert werden, und werden automatisch beendet, wenn sie nicht mehr verwendet werden.

Dynamisch ausführbare Dienste

Dieses Feature ist nur für native Dienste verfügbar, deren Lebenszyklen von init und servicemanager gesteuert werden können. Dienste in Anwendungspaketen werden nicht unterstützt und sollten stattdessen gebundene Dienste verwenden.

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

Init-RC-Datei eines Dienstes konfigurieren

Wenn Sie einen Dienst dynamisch ausführen möchten, fügen Sie der init-Datei .rc des Dienstes nach der führenden service <name> <cmd>-Zeile die folgenden Optionen hinzu.

interface aidl serviceName
disabled
oneshot

Mit diesen Optionen haben Sie folgende Möglichkeiten:

  • 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 von servicemanager erwarteten Namen entsprechen und können vom Prozessnamen abweichen.
  • disabled: verhindert, dass der Dienst beim Booten automatisch gestartet wird.
  • oneshot: Verhindert, dass der Dienst bei jedem Beenden automatisch neu gestartet wird.

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

Beispiele:

Dienst registrieren

Jeder Dienst wird mit servicemanager erstellt und registriert. Die Registrierung erfolgt häufig in einer Datei namens main.cpp, die Implementierung kann jedoch variieren. Die Registrierung sieht normalerweise 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 anhand ihrer Referenzanzahl zu beenden.

Beispiele:

AIDL-Dienstclients konfigurieren

Dienst abrufen

Zum Abrufen eines Lazy Service muss der Dienst gestartet und dann abgerufen werden. Durch den Aufruf von getService im Dienstmanager wird der Dienst gestartet. In der Regel sollten Sie den Dienst jedoch abrufen, sobald er verfügbar ist. Verwenden Sie in diesem Fall die waitForService-Varianten. Informationen zur Verwendung finden Sie in der Back-End-spezifischen Dokumentation.

Dienst freigeben

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

Beispiele:

Herunterfahren vorübergehend deaktivieren

Wenn ein Dienst unabhängig ausgeführt werden soll, bis bestimmte Aufgaben abgeschlossen sind, und dann zum dynamischen Verhalten wechseln möchten, können Sie mit LazyServiceRegistrar::forcePersist das dynamische Herunterfahren ein- und ausschalten. Wird dies serverseitig aufgerufen, sollte der Dienst vor registerService aufgerufen werden.

Beispiel: apexservice