Dynamiczne uruchamianie usług AIDL

Począwszy od Androida 11, natywne usługi AIDL działające na partycji systemowej można uruchamiać i zatrzymywać dynamicznie w miarę potrzeb. Usługi dynamiczne uruchamiają się w momencie pierwszego żądania i zatrzymują się automatycznie, gdy nie są już używane.

Usługi, które mogą działać dynamicznie

Ta funkcja jest dostępna tylko dla usług natywnych, których cykle życia mogą być kontrolowane przez init i servicemanager . Usługi w ramach pakietów aplikacji nie są obsługiwane i zamiast tego powinny korzystać z usług powiązanych .

Zamknięcie dynamiczne polega na zamknięciu procesu, w którym działa usługa. Jeśli w tym samym procesie istnieje wiele usług, wszystkie muszą być zarejestrowane jako dynamiczne, aby były kompatybilne z tą funkcją. Proces ten zostanie następnie zamknięty, gdy wszystkie usługi nie będą używane.

Konfigurowanie pliku init .rc usługi

Aby dynamicznie uruchamiać usługę, dodaj następujące opcje do pliku init .rc usługi po wiodącym wierszu service <name> <cmd> .

interface aidl serviceName
disabled
oneshot

Opcje te wykonują następujące czynności:

  • interface aidl serviceName : Umożliwia servicemanager znalezienie usługi. Jeśli usługa korzysta z wielu interfejsów, zadeklaruj każdy interfejs w osobnej linii. Nazwy te muszą być dokładnie takie, jakich oczekuje servicemanager i mogą różnić się od nazwy procesu.
  • disabled : Uniemożliwia automatyczne uruchamianie usługi podczas rozruchu.
  • oneshot : Uniemożliwia automatyczne ponowne uruchomienie usługi po każdym jej zatrzymaniu.

Aby uzyskać więcej informacji, zobacz plik Readme dotyczący języka początkowego systemu Android w AOSP.

Przykłady:

Rejestracja usługi

Każda usługa jest tworzona i rejestrowana w servicemanager . Rejestracja często odbywa się w pliku o nazwie main.cpp , ale implementacja może być różna. Rejestracja wygląda zazwyczaj mniej więcej tak:

using android::defaultServiceManager;

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

Rejestracja jest czasami pobierana przez BinderService::publish lub BinderService::instantiate , które wywołują powyższy kod.

Aby zarejestrować usługę jako dynamiczną, zamień jej kod rejestracyjny na następujący:

#include <binder/LazyServiceRegistrar.h>

using android::binder::LazyServiceRegistrar;

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

servicemanager komunikuje się z LazyServiceRegistrar , aby zamknąć usługi na podstawie ich liczby odwołań.

Przykłady:

Konfigurowanie klientów usług AIDL

Uzyskanie usługi

Aby odzyskać leniwą usługę, należy ją uruchomić, a następnie pobrać. Wywołanie getService w menedżerze usług uruchomi usługę, ale zazwyczaj chcesz uzyskać usługę, gdy tylko będzie dostępna, i należy zastosować warianty waitForService . Zobacz dokumentację specyficzną dla backendu , jak z nich korzystać.

Zwolnienie usługi

Dynamiczne zamknięcie opiera się na zliczaniu referencji, dlatego klientom nie wolno zatrzymywać usługi, gdy nie jest ona używana.

Przykłady:

Tymczasowe wyłączenie zamykania

Jeśli chcesz, aby usługa działała niezależnie do czasu zakończenia określonych zadań, a następnie przełączyła się na zachowanie dynamiczne, możesz użyć LazyServiceRegistrar::forcePersist do włączania i wyłączania dynamicznego zamykania. Jeśli jest to wywoływane ze strony serwera, powinno zostać wywołane przed registerService .

Przykład: apexservice