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

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

Сервисы, способные работать в динамическом режиме.

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

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

Настройте файл инициализации (.rc) службы.

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

interface aidl serviceName
disabled
oneshot

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

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

Для получения более подробной информации см. файл Readme, содержащий описание языка инициализации 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