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ę potrzeby. Usługi dynamiczne są uruchamiane po pierwszym żądaniu i automatycznie zatrzymywane, 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 cykl życia można kontrolować za pomocą funkcji initservicemanager. Usługi w pakietach aplikacji nie są obsługiwane. Należy zamiast nich używać usług powiązanych.

Dynamiczne zamykanie polega na zamykaniu procesu, w którym działa usługa. Jeśli w ramach tego samego procesu występuje wiele usług, wszystkie muszą być zarejestrowane jako dynamiczne, aby były zgodne z tą funkcją. Ten proces zostanie zamknięty, 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

Te opcje umożliwiają:

  • interface aidl serviceName: umożliwia servicemanager znalezienie usługi. Jeśli usługa korzysta z kilku 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 uruchamiania.
  • oneshot: uniemożliwia automatyczne uruchamianie usługi po jej zatrzymaniu.

Więcej informacji znajdziesz w Readme na temat języka inicjalizacji Androida w AOSP.

Przykłady:

Rejestrowanie 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 się różnić. Rejestracja wygląda zwykle 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);

Usługa servicemanager komunikuje się z usługą LazyServiceRegistrar, aby wyłączyć usługi na podstawie ich liczby referencyjnej.

Przykłady:

Konfigurowanie klientów usługi AIDL

Uzyskiwanie dostępu do usługi

Aby pobrać usługę typu lazy, musisz ją uruchomić, a następnie pobrać. Wywołanie getService w menedżerze usługi uruchamia usługę, ale zwykle chcesz, aby usługa była dostępna od razu, dlatego należy użyć wariantu waitForService. Więcej informacji o każdym z tych formatów znajdziesz w dokumentacji dotyczącej backendu.

Zwolnij usługę

Dynamiczne zamykanie jest oparte na zliczaniu odwołań, więc klienci nie mogą przechowywać 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 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