A partir do Android 11, os serviços AIDL nativos em execução na partição do sistema podem ser iniciados e interrompidos dinamicamente conforme necessário. Os serviços dinâmicos iniciam quando são solicitados pela primeira vez e param automaticamente quando não estão mais em uso.
Serviços que podem ser executados dinamicamente
Este recurso está disponível apenas para serviços nativos cujos ciclos de vida podem ser controlados por init
e servicemanager
. Os serviços dentro de pacotes de aplicativos não são suportados e devem usar serviços vinculados .
O desligamento dinâmico funciona encerrando o processo no qual o serviço é executado. Caso existam vários serviços no mesmo processo, todos eles deverão ser cadastrados como dinâmicos para serem compatíveis com este recurso. Esse processo será encerrado quando todos os serviços não forem utilizados.
Configurando o arquivo init .rc de um serviço
Para executar um serviço dinamicamente, adicione as seguintes opções ao arquivo init .rc
do serviço após a linha inicial service <name> <cmd>
.
interface aidl serviceName
disabled
oneshot
Essas opções fazem o seguinte:
-
interface aidl serviceName
: permite queservicemanager
encontre o serviço. Se o serviço usar diversas interfaces, declare cada interface em sua própria linha. Esses nomes devem ser exatamente o queservicemanager
espera e podem ser diferentes do nome do processo. -
disabled
: Impede que o serviço seja iniciado automaticamente na inicialização. -
oneshot
: Impede que o serviço seja reiniciado automaticamente sempre que for interrompido.
Para obter mais informações, consulte o Leiame do idioma de inicialização do Android no AOSP.
Exemplos:
Registrando um serviço
Cada serviço é criado e registrado no servicemanager
. O registro geralmente ocorre em um arquivo chamado main.cpp
, mas a implementação pode variar. O registro geralmente é mais ou menos assim:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
O registro às vezes é abstraído por BinderService::publish
ou BinderService::instantiate
, que chamam o código acima.
Para registrar um serviço como dinâmico, substitua seu código de registro pelo seguinte:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager
se comunica com LazyServiceRegistrar
para encerrar serviços com base em suas contagens de referência.
Exemplos:
Configurando clientes de serviço AIDL
Obtendo o serviço
Para recuperar um serviço lento, o serviço deve ser iniciado e depois recuperado. Chamar getService
no gerenciador de serviços iniciará o serviço, mas geralmente você deseja obter o serviço assim que estiver disponível e variantes waitForService
devem ser usadas. Consulte a documentação específica do backend sobre como usá-los.
Liberando o serviço
O desligamento dinâmico é baseado na contagem de referência, portanto os clientes não devem manter o serviço quando ele não estiver em uso.
Exemplos:
Desativando temporariamente o desligamento
Se quiser que um serviço seja executado de forma independente até que determinadas tarefas sejam concluídas e depois mude para um comportamento dinâmico, você pode usar LazyServiceRegistrar::forcePersist
para ativar e desativar o desligamento dinâmico. Se for chamado do lado do servidor, deverá ser chamado antes de registerService
.
Exemplo: apexservice