Начиная с Android 11, собственные службы AIDL, работающие в системном разделе, можно запускать и останавливать динамически по мере необходимости. Динамические службы запускаются при первом запросе и автоматически останавливаются, когда они больше не используются.
Службы, которые могут работать динамически
Эта функция доступна только для собственных служб, жизненный цикл которых может контролироваться с помощью init
и servicemanager
. Службы в пакетах приложений не поддерживаются, и вместо них следует использовать связанные службы .
Динамическое завершение работы осуществляется путем закрытия процесса, в котором работает служба. Если в одном процессе существует несколько служб, все они должны быть зарегистрированы как динамические, чтобы быть совместимыми с этой функцией. Затем этот процесс завершится, когда все службы не будут использоваться.
Настройка файла инициализации .rc службы
Чтобы запустить службу динамически, добавьте следующие параметры в файл инициализации .rc
службы после первой строки service <name> <cmd>
.
interface aidl serviceName
disabled
oneshot
Эти параметры делают следующее:
-
interface aidl serviceName
: позволяетservicemanager
найти службу. Если служба использует несколько интерфейсов, объявите каждый интерфейс в отдельной строке. Эти имена должны соответствовать ожиданиямservicemanager
и могут отличаться от имени процесса. -
disabled
: предотвращает автоматический запуск службы при загрузке. -
oneshot
: предотвращает автоматический перезапуск службы каждый раз при ее остановке.
Дополнительные сведения см. в файле сведений о языке инициализации Android в AOSP.
Примеры:
Зарегистрировать услугу
Каждая служба создается и регистрируется в servicemanager
. Регистрация часто происходит в файле с именем main.cpp
, но реализация может отличаться. Регистрация обычно выглядит примерно так:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
Иногда регистрация абстрагируется с помощью BinderService::publish
или BinderService::instantiate
, которые вызывают приведенный выше код.
Чтобы зарегистрировать службу как динамическую, замените ее регистрационный код следующим:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager
связывается с LazyServiceRegistrar
для отключения служб на основе их количества ссылок.
Примеры:
Настройка клиентов службы AIDL
Получить услугу
Чтобы получить отложенную службу, ее необходимо запустить, а затем получить. Вызов getService
в диспетчере служб запустит службу, но обычно вы хотите получить службу, как только она станет доступна, и следует использовать варианты waitForService
. О том, как их использовать, см. документацию по конкретной серверной части .
Выпустить услугу
Динамическое отключение основано на подсчете ссылок, поэтому клиенты не должны удерживать службу, когда она не используется.
Примеры:
Временно отключить выключение
Если вы хотите, чтобы служба работала независимо до завершения определенных задач, а затем переключалась на динамическое поведение, вы можете использовать LazyServiceRegistrar::forcePersist
для включения и выключения динамического завершения работы. Если это вызывается со стороны сервера, его следует вызывать до registerService
.
Пример: apexservice