A partir de Android 11, los servicios AIDL nativos que se ejecutan en la partición del sistema se pueden iniciar y detener de forma dinámica según sea necesario. Los servicios dinámicos se inician cuando se solicitan por primera vez y se detienen automáticamente cuando ya no están en uso.
Servicios que se pueden ejecutar de forma dinámica
Esta función solo está disponible para servicios nativos cuyos ciclos de vida se pueden controlar con init
y servicemanager
. Los servicios dentro de los paquetes de apps no se admiten y, en su lugar, deben usar servicios vinculados.
El cierre dinámico funciona apagando el proceso en el que se ejecuta el servicio. Si existen varios servicios en el mismo proceso, todos deben registrarse como dinámicos para ser compatibles con esta función. Luego, ese proceso se cerrará cuando no se usen todos los servicios.
Configura el archivo .rc de inicio de un servicio
Para ejecutar un servicio de forma dinámica, agrega las siguientes opciones al archivo .rc
de inicio del servicio después de la línea service <name> <cmd>
inicial.
interface aidl serviceName
disabled
oneshot
Estas opciones hacen lo siguiente:
interface aidl serviceName
: Permite queservicemanager
encuentre el servicio. Si el servicio usa varias interfaces, declara cada una en su propia línea. Estos nombres deben ser exactamente lo queservicemanager
espera y pueden diferir del nombre del proceso.disabled
: Evita que el servicio se inicie automáticamente durante el inicio.oneshot
: Evita que el servicio se reinicie automáticamente cada vez que se detiene.
Para obtener más información, consulta el archivo readme sobre el lenguaje Init de Android en el AOSP.
Ejemplos:
Cómo registrar un servicio
Cada servicio se crea y registra con servicemanager
. El registro suele ocurrir en un archivo llamado main.cpp
, pero la implementación puede variar. El registro suele verse de la siguiente manera:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
A veces, BinderService::publish
o BinderService::instantiate
abstraen el registro, que llama al código anterior.
Para registrar un servicio como dinámico, reemplaza el código de registro por lo siguiente:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager
se comunica con LazyServiceRegistrar
para cerrar los servicios según sus recuentos de referencias.
Ejemplos:
Configura clientes de servicio AIDL
Cómo obtener el servicio
Para recuperar un servicio diferido, se debe iniciar y recuperar el servicio.
Si llamas a getService
en el administrador de servicios, se iniciará el servicio, pero, por lo general, querrás obtenerlo en cuanto esté disponible, y se deben usar las variantes de waitForService
. Consulta la documentación específica del backend para saber cómo usarlos.
Libera el servicio
El cierre dinámico se basa en el recuento de referencias, por lo que los clientes no deben conservar el servicio cuando no está en uso.
Ejemplos:
Inhabilita el cierre de forma temporal
Si deseas que un servicio se ejecute de forma independiente hasta que se completen ciertas tareas y, luego, cambie al comportamiento dinámico, puedes usar LazyServiceRegistrar::forcePersist
para activar o desactivar el cierre dinámico. Si se llama a esto desde el servidor, se debe llamar antes de registerService
.
Ejemplo: apexservice