동적으로 AIDL 서비스 실행하기

Android 11부터 시스템 파티션에서 실행되는 네이티브 AIDL 서비스를 필요에 따라 동적으로 시작하고 중지할 수 있습니다. 동적 서비스는 처음 요청될 때 시작되고 더 이상 사용되지 않으면 자동으로 중지됩니다.

동적으로 실행될 수 있는 서비스

이 기능은 수명 주기를 initservicemanager로 제어할 수 있는 네이티브 서비스에서만 사용할 수 있습니다. 앱 패키지 내의 서비스는 지원되지 않으며 대신 바인드된 서비스를 사용해야 합니다.

동적 종료는 서비스가 실행되는 프로세스를 종료하여 작동합니다. 여러 서비스가 동일한 프로세스에 있다면 이 기능과 호환되도록 모든 서비스를 동적으로 등록해야 합니다. 그러면 모든 서비스가 사용되지 않을 때 프로세스가 종료됩니다.

서비스의 init .rc 파일 구성하기

서비스를 동적으로 실행하려면 앞의 service <name> <cmd> 줄 뒤에 다음 옵션을 서비스의 init .rc 파일에 추가합니다.

interface aidl serviceName
disabled
oneshot

이러한 옵션은 다음 작업을 실행합니다.

  • interface aidl serviceName: servicemanager가 서비스를 찾을 수 있습니다. 서비스에서 여러 인터페이스를 사용한다면 각 인터페이스를 자체 줄에 선언합니다. 이러한 이름은 servicemanager에서 예상하는 것과 정확히 일치해야 하고 프로세스 이름과는 다를 수도 있습니다.
  • disabled: 부팅 시 서비스가 자동으로 시작되는 것을 방지합니다.
  • oneshot: 서비스가 중지될 때마다 자동으로 다시 시작되는 것을 방지합니다.

자세한 내용은 AOSP의 Android Init 언어 Readme를 참고하세요.

예를 들면 다음과 같습니다.

서비스 등록하기

각 서비스는 servicemanager로 만들어지고 등록됩니다. 등록은 main.cpp 파일에서 발생할 때가 많지만 다르게 구현될 수도 있습니다. 등록 코드는 일반적으로 다음과 같습니다.

using android::defaultServiceManager;

defaultServiceManager()->addService(serviceName, service);

등록은 위의 코드를 호출하는 BinderService::publish 또는 BinderService::instantiate로 추상화되기도 합니다.

서비스를 동적으로 등록하려면 등록 코드를 다음으로 대체합니다.

#include <binder/LazyServiceRegistrar.h>

using android::binder::LazyServiceRegistrar;

auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);

servicemanagerLazyServiceRegistrar와 통신하여 참조 횟수에 따라 서비스를 종료합니다.

예를 들면 다음과 같습니다.

AIDL 서비스 클라이언트 구성하기

서비스 가져오기

지연 서비스를 가져오려면 서비스를 시작한 다음 가져와야 합니다. 서비스 관리자에서 getService를 호출하면 서비스가 시작되지만, 대부분의 경우 서비스가 사용 가능한 상태가 되자마자 가져와야 하며 waitForService 변형을 사용하는 것이 좋습니다. 변형을 사용하는 방법은 백엔드 관련 도움말을 참고하세요.

서비스 해제하기

동적 종료는 참조 횟수에 기반하므로 클라이언트는 서비스가 사용되지 않을 때 서비스를 유지해서는 안 됩니다.

예를 들면 다음과 같습니다.

일시적으로 종료 사용 중지하기

특정 작업이 완료될 때까지 서비스를 독립적으로 실행한 다음 동적 동작으로 전환하려면 LazyServiceRegistrar::forcePersist를 사용하여 동적 종료를 사용 설정하거나 중지할 수 있습니다. 이 작업을 서버 측에서 호출한다면 registerService 전에 호출해야 합니다.

예: apexservice