No Android 11 e versões mais recentes, os serviços nativos da AIDL em execução na partição do sistema podem ser iniciados e interrompidos dinamicamente, conforme necessário. Os serviços dinâmicos começam quando são solicitados pela primeira vez e são interrompidos automaticamente quando não estão mais em uso.
Serviços que podem ser executados dinamicamente
Esse recurso está disponível apenas para serviços nativos com ciclos de vida que podem ser
controlados por init
e servicemanager
. Os serviços dentro de pacotes de apps não têm
suporte e precisam usar serviços vinculados.
O encerramento dinâmico encerra o processo em que o serviço é executado. Se houver vários serviços no mesmo processo, todos eles precisarão ser registrados como dinâmicos para serem compatíveis com esse recurso. Esse processo será encerrado quando todos os serviços deixarem de ser usados.
Configurar 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 service <name> <cmd>
inicial.
interface aidl serviceName
disabled
oneshot
Essas opções fazem o seguinte:
interface aidl serviceName
: permite que oservicemanager
encontre o serviço. Se o serviço usar várias interfaces, declare cada uma delas na própria linha. Esses nomes precisam ser exatamente o que oservicemanager
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 mais informações, consulte o Readme da linguagem Init do Android no AOSP.
Exemplos:
Registrar 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 tem esta aparência:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
Às vezes, o registro é abstraído por BinderService::publish
ou
BinderService::instantiate
, que chamam o código acima.
Para registrar um serviço como dinâmico, substitua o 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 nas contagens de referência.
Exemplos:
Configurar clientes de serviço da AIDL
Acessar o serviço
Para recuperar um serviço lento, ele precisa ser iniciado e recuperado.
Chamar getService
no gerenciador de serviços iniciará o serviço, mas normalmente é melhor recebê-lo assim que ele estiver disponível, e é necessário usar as variantes waitForService
. Consulte a documentação específica do
back-end
para saber como usá-los.
Liberar o serviço
O encerramento dinâmico é baseado na contagem de referências. Assim, os clientes não podem manter o serviço quando ele não está em uso.
Exemplos:
Desativar temporariamente o encerramento
Se você quiser que um serviço seja executado de forma independente até que determinadas tarefas sejam concluídas e, em seguida, mude para o comportamento dinâmico, use LazyServiceRegistrar::forcePersist
para ativar e desativar o encerramento dinâmico. Se isso for chamado do lado do servidor, deverá ser chamado antes de registerService
.
Exemplo: apexservice