動態執行 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 Language Readme」

例如:

註冊服務

每個服務都會建立並向 servicemanager 註冊。註冊通常發生在名為 main.cpp 的檔案中,但實作方式可能有所不同。註冊程序通常如下所示:

using android::defaultServiceManager;

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

有時 BinderService::publishBinderService::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