W Androidzie 11 i nowszych wersjach natywne usługi AIDL działające w partycji systemowej można uruchamiać i zatrzymywać dynamicznie w zależności od potrzeb. Usługi dynamiczne uruchamiają się, gdy po raz pierwszy zostanie wysłane do nich żądanie, i automatycznie zatrzymują się, 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 cyklem życia można sterować za pomocą poleceń init i servicemanager. Usługi w pakietach aplikacji nie są
obsługiwane i powinny zamiast tego korzystać z usług powiązanych.
Dynamiczne zamykanie polega na zamykaniu procesu, w którym działa usługa. Jeśli w tym samym procesie istnieje kilka usług, wszystkie muszą być zarejestrowane jako dynamiczne, aby były zgodne z tą funkcją. Gdy wszystkie usługi nie będą używane, proces zostanie wyłączony.
Konfigurowanie pliku init .rc usługi
Aby usługa działała dynamicznie, dodaj te opcje do pliku init
.rc usługi po wiodącym service <name> <cmd> wierszu.
interface aidl serviceName
disabled
oneshot
Te opcje wykonują te czynności:
interface aidl serviceName: umożliwia usłudzeservicemanagerznalezienie usługi. Jeśli usługa korzysta z wielu interfejsów, zadeklaruj każdy z nich w osobnym wierszu. Te nazwy muszą być dokładnie takie, jakich oczekujeservicemanager, i mogą się różnić od nazwy procesu.disabled: uniemożliwia automatyczne uruchamianie usługi podczas uruchamiania.oneshot: uniemożliwia automatyczne ponowne uruchamianie usługi po każdym jej zatrzymaniu.
Więcej informacji znajdziesz w pliku Readme języka init Androida w AOSP.
Przykłady:
Rejestrowanie usługi
Każda usługa jest tworzona i rejestrowana w usłudze servicemanager. Rejestracja często odbywa się w pliku o nazwie main.cpp, ale implementacja może się różnić. Rejestracja zwykle wygląda tak:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
Rejestracja jest czasami abstrahowana przez BinderService::publish lub BinderService::instantiate, które wywołują powyższy kod.
Aby zarejestrować usługę jako dynamiczną, zastąp jej kod rejestracji tym kodem:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager komunikuje się z LazyServiceRegistrar, aby wyłączyć usługi na podstawie ich liczby odwołań.
Przykłady:
Konfigurowanie klientów usług AIDL
Pobieranie usługi
Aby pobrać usługę leniwą, należy ją uruchomić, a następnie pobrać.
Wywołanie getService w menedżerze usług spowoduje uruchomienie usługi, ale zwykle chcesz pobrać usługę, gdy tylko będzie dostępna, dlatego należy używać wariantów waitForService. Informacje o tym, jak ich używać, znajdziesz w dokumentacji dotyczącej backendu.
Zwalnianie usługi
Dynamiczne zamykanie opiera się na zliczaniu odwołań, dlatego klienci nie mogą utrzymywać usługi, gdy nie jest ona używana.
Przykłady:
Tymczasowe wyłączanie zamykania
Jeśli chcesz, aby usługa działała niezależnie do momentu wykonania określonych zadań, a następnie przełączyła się na zachowanie dynamiczne, możesz użyć LazyServiceRegistrar::forcePersist, aby włączać i wyłączać dynamiczne zamykanie. Jeśli jest to wywoływane po stronie serwera, należy to zrobić przed wywołaniem registerService.
Przykład: apexservice