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 são iniciados 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
Esse recurso está disponível apenas para serviços nativos cujos ciclos de vida podem ser
controlados por init
e servicemanager
. Os serviços em pacotes de apps não são
compatíveis e precisam usar serviços vinculados
em vez disso.
O encerramento dinâmico funciona encerrando 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 não forem usados.
Configurar um arquivo .rc de inicialização de serviço
Para executar um serviço de forma dinâmica, 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 queservicemanager
encontre o serviço. Se o serviço usar várias interfaces, declare cada uma em uma linha separada. Esses nomes precisam 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 mais informações, consulte o Readme da linguagem de inicialização do Android (link em inglês) no AOSP.
Exemplos:
Registrar um serviço
Cada serviço é criado e registrado com servicemanager
. O registro geralmente
ocorre em um arquivo chamado main.cpp
, mas a implementação pode variar. O
registro geralmente é algo assim:
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 dele pelo seguinte:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
O servicemanager
se comunica com o LazyServiceRegistrar
para encerrar serviços com base nas contagens de referência.
Exemplos:
Configurar clientes de serviço AIDL
Acessar o serviço
Para recuperar um serviço lazy, ele precisa ser iniciado e recuperado.
Chamar getService
no gerenciador de serviços vai iniciar o serviço, mas geralmente,
você quer receber o serviço assim que ele estiver disponível, e as variantes
waitForService
devem ser usadas. Consulte a documentação específica do back-end sobre como usar esses recursos.
Liberar o serviço
O desligamento dinâmico se baseia na contagem de referências. Portanto, os clientes não podem manter o serviço quando ele não está em uso.
Exemplos:
Desativar temporariamente o desligamento
Se você 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, use
LazyServiceRegistrar::forcePersist
para ativar e desativar o desligamento dinâmico. Se
isso for chamado do lado do servidor, será necessário fazer isso antes de
registerService
.
Exemplo: apexservice