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

Начиная с 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 .

Пример: апекссервис