Динамический запуск служб AIDL

Начиная с Android 11, собственные службы AIDL, работающие в системном разделе, могут запускаться и останавливаться динамически по мере необходимости. Динамические службы запускаются при первом запросе и автоматически останавливаются, когда они больше не используются.

Службы, которые могут работать динамически

Эта функция доступна только для собственных служб, жизненные циклы которых могут контролироваться init и servicemanager . Службы в пакетах приложений не поддерживаются и должны использовать вместо этого привязанные службы .

Динамическое выключение работает путем выключения процесса, в котором запущена служба. Если в одном процессе существует несколько служб, все они должны быть зарегистрированы как динамические, чтобы быть совместимыми с этой функцией. Затем этот процесс будет выключен, когда все службы не будут использоваться.

Настройте файл init .rc службы

Для динамического запуска службы добавьте следующие параметры в файл init .rc службы после первой строки service <name> <cmd> .

interface aidl serviceName
disabled
oneshot

Эти опции выполняют следующие действия:

  • interface aidl serviceName : Позволяет servicemanager найти службу. Если служба использует несколько интерфейсов, объявите каждый интерфейс в отдельной строке. Эти имена должны быть именно такими, какие ожидает servicemanager , и могут отличаться от имени процесса.
  • disabled : предотвращает автоматический запуск службы при загрузке.
  • oneshot : предотвращает автоматический перезапуск службы после каждой остановки.

Более подробную информацию см. в файле Readme Android Init Language в 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