Android 11 以降、システム パーティションで実行されるネイティブ AIDL サービスは、必要に応じて動的に開始および停止できます。動的なサービスは、最初にリクエストされたときに開始し、使用されなくなると自動的に停止します。
動的な実行が可能なサービス
この機能は、ライフサイクルを init
と servicemanager
で制御できるネイティブ サービスでのみ使用できます。アプリ パッケージ内のサービスはサポートされていないため、代わりにバインドされたサービスを使用します。
動的なシャットダウンは、そのサービスを実行しているプロセスをシャットダウンすることで動作します。 同じプロセス内に複数のサービスが存在する場合、この機能との互換性を確保するためには、すべてのサービスを動的として登録する必要があります。そのプロセスは、すべてのサービスが使用されていないときにシャットダウンします。
サービスの init .rc ファイルの設定
サービスを動的に実行するには、サービスの init .rc
ファイルの先頭行「service <name> <cmd>
」の下に次のオプションを追加します。
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);
servicemanager
は LazyServiceRegistrar
と通信し、参照数に基づいてサービスをシャットダウンします。
例:
AIDL サービス クライアントの設定
サービスの取得
遅延サービスを取得するには、サービスを開始して取得する必要があります。サービス マネージャーで getService
を呼び出すとサービスが開始されますが、通常はそのサービスが使用可能になった時点で取得するために waitForService
バリアントを使用する必要があります。これらの使用方法については、バックエンド固有のドキュメントをご覧ください。
サービスの解放
動的なシャットダウンは参照数に基づいて行われるため、クライアントは使用していないサービスを参照し続けるべきではありません。
例:
シャットダウンの一時的な無効化
サービスを非動的に実行し、特定のタスクが完了した後で動的に切り替える場合は、LazyServiceRegistrar::forcePersist
を使用して動的なシャットダウンのオンとオフを切り替えます。これをサーバー側から呼び出す場合は、registerService
の前に呼び出す必要があります。
例: apexservice