Dynamiczne uruchamianie usług AIDL

Od Androida 11 natywne usługi AIDL działające w partycji systemowej można dynamicznie uruchamiać i zatrzymywać w miarę potrzeb. Usługi dynamiczne uruchamiają się po pierwszym żądaniu i zatrzymują się automatycznie, gdy nie są już używane.

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

Ta funkcja jest dostępna tylko w przypadku usług natywnych, których cykle życia mogą być kontrolowane przez init i servicemanager. Usługi w pakietach aplikacji nie są obsługiwane i powinny powinny używać powiązanych usług.

Dynamiczne wyłączanie polega na zatrzymaniu procesu, w którym działa usługa. Jeśli w ramach tego samego procesu istnieje wiele usług, wszystkie muszą być zarejestrowane jako dynamiczne, by były zgodne z tą funkcją. Ten proces zostanie wyłączony, gdy wszystkie usługi nie będą używane.

Konfigurowanie pliku .rc init usługi

Aby dynamicznie uruchamiać usługę, dodaj poniższe opcje do pliku inicjowanego przez usługę .rc po początkowym wierszu service <name> <cmd>.

interface aidl serviceName
disabled
oneshot

Za pomocą tych opcji możesz:

  • interface aidl serviceName: umożliwia usłudze servicemanager znalezienie usługi. Jeśli usługa korzysta z wielu interfejsów, zadeklaruj każdy z nich w osobnym wierszu. Te nazwy muszą być zgodne z oczekiwaniami usługi servicemanager i mogą różnić się od nazwy procesu.
  • disabled: zapobiega automatycznemu uruchamianiu usługi podczas rozruchu.
  • oneshot: zapobiega automatycznemu ponownemu uruchomieniu usługi przy każdym zatrzymaniu.

Więcej informacji znajdziesz w dokumentacji Android Init Language Readme (w języku angielskim) w AOSP.

Przykłady:

Rejestrowanie usługi

Każda usługa zostanie utworzona i zarejestrowana w servicemanager. Rejestracja często odbywa się w pliku o nazwie main.cpp, ale implementacja może być różna. Rejestracja zwykle wygląda tak:

using android::defaultServiceManager;

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

Rejestracja może być czasami wyodrębniona przez kod BinderService::publish lub BinderService::instantiate, który wywołuje powyższy kod.

Aby zarejestrować usługę jako dynamiczną, zastąp jej kod rejestracji następującym:

#include <binder/LazyServiceRegistrar.h>

using android::binder::LazyServiceRegistrar;

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

servicemanager komunikuje się z LazyServiceRegistrar w celu wyłączania usług na podstawie liczby referencji.

Przykłady:

Skonfiguruj klienty usługi AIDL

Skorzystaj z usługi

Aby pobrać leniwą usługę, należy ją uruchomić, a następnie pobrać. Wywołanie usługi getService w menedżerze usługi uruchamia usługę, ale zwykle chcesz uzyskać ją, gdy tylko będzie dostępna, i należy używać wariantów waitForService. Informacje o tym, jak ich używać, znajdziesz w dokumentacji backendu.

Zwolnij usługę

Dynamiczne wyłączanie opiera się na liczeniu plików referencyjnych, więc klienci nie mogą zatrzymać usługi, gdy nie jest używana.

Przykłady:

Tymczasowo wyłącz wyłączenie

Jeśli chcesz, aby usługa działała niezależnie do chwili wykonania określonych zadań, a następnie przełączy się na zachowanie dynamiczne, możesz za pomocą LazyServiceRegistrar::forcePersist włączać i wyłączać dynamiczne wyłączanie. Jeśli jest to wywoływane po stronie serwera, powinno być wywoływane przed poleceniem registerService.

Przykład: apexservice