No Android 11 e versões mais recentes, 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 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 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 desligamento dinâmico funciona interrompendo o processo em que o serviço é executado. Se vários serviços existirem no mesmo processo, todos eles precisarão ser registrados como dinâmicos para serem compatíveis com esse recurso. Esse processo será desligado quando todos os serviços não forem 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 principal service <name> <cmd>.
interface aidl serviceName
disabled
oneshot
Essas opções fazem o seguinte:
interface aidl serviceName: permite queservicemanagerencontre 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 queservicemanagerespera 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 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 é 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 o código de registro dele pelo seguinte:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager se comunica com LazyServiceRegistrar para desligar serviços com base nas contagens de referência.
Exemplos:
Configurar clientes de serviço AIDL
Receber o serviço
Para recuperar um serviço lento, ele precisa ser iniciado e recuperado.
Chamar getService no administrador do serviço vai iniciar o serviço, mas geralmente você quer receber o serviço assim que ele estiver disponível, e as variantes waitForService precisam ser usadas. Consulte a documentação
específica do back-end
sobre como usá-las.
Liberar o serviço
O desligamento dinâmico é baseado na contagem de referências. Portanto, os clientes não podem manter o serviço quando ele não estiver 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, em seguida, mude para o comportamento dinâmico, use LazyServiceRegistrar::forcePersist para ativar e desativar o desligamento dinâmico. Se isso for chamado do lado do servidor, ele precisará ser chamado antes de registerService.
Exemplo: apexservice