Starting in Android 11, native AIDL services running in the system partition can be started and stopped dynamically as they are needed. Dynamic services start when they are first requested and automatically stop when they are no longer in use.
Services that can run dynamically
This feature is available only for native services whose lifecycles can be
controlled by init
and servicemanager
. Services within app packages are not
supported and should use bound services
instead.
Dynamic shutdown works by shutting down the process in which the service runs. If multiple services exist in the same process, all of them must be registered as dynamic to be compatible with this feature. That process will then shut down when all of the services are unused.
Configure a service's init .rc file
To run a service dynamically, add the following options to the service’s init
.rc
file after the leading service <name> <cmd>
line.
interface aidl serviceName
disabled
oneshot
These options do the following:
interface aidl serviceName
: Allowsservicemanager
to find the service. If the service uses multiple interfaces, declare each interface on its own line. These names must be exactly whatservicemanager
expects and may differ from the process name.disabled
: Prevents the service from automatically starting at boot.oneshot
: Prevents the service from automatically restarting each time it is stopped.
For more information, see the Android Init Language Readme in AOSP.
Examples:
Register a service
Each service is created and registered with servicemanager
. Registration often
occurs in a file named main.cpp
, but the implementation can vary. The
registration usually looks something like this:
using android::defaultServiceManager;
defaultServiceManager()->addService(serviceName, service);
Registration is sometimes abstracted by BinderService::publish
or
BinderService::instantiate
, which call the above code.
To register a service as dynamic, replace its registration code with the following:
#include <binder/LazyServiceRegistrar.h>
using android::binder::LazyServiceRegistrar;
auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);
servicemanager
communicates with LazyServiceRegistrar
to shut down services
based on their reference counts.
Examples:
Configure AIDL service clients
Get the service
To retrieve a lazy service, the service must be started and then retrieved.
Calling getService
on the service manager will start the service, but usually,
you want to get the service as soon as it is available, and waitForService
variants should be used. See backend-specific
documentation
on how to use these.
Release the service
Dynamic shutdown is based on reference counting, so clients must not hold onto the service when it is not in use.
Examples:
Temporarily disable shutdown
If you want a service to run independently until certain tasks are complete and
then switch to dynamic behavior, you can use
LazyServiceRegistrar::forcePersist
to toggle dynamic shutdown on and off. If
this is called from the server side, it should be called before
registerService
.
Example: apexservice