動態執行 AIDL 服務

自 Android 11 起,在系統分區中執行的原生 AIDL 服務可視需要動態啟動及停止。動態服務會在首次要求時啟動,並會在不再使用時自動停止運作。

可動態執行的服務

這項功能僅適用於生命週期可由 initservicemanager 控管生命週期的原生服務。系統不支援應用程式套件中的服務,請改用繫結服務

動態關閉的運作方式是關閉服務的執行程序。如果同一程序中有多個服務存在,所有服務都必須註冊為動態,才能與此功能相容。未使用所有服務時,這項程序就會關閉。

設定服務的 init .rc 檔案

如要動態執行服務,請將下列選項新增至服務的 init.rc 檔案,開頭的 service <name> <cmd> 行後方。

interface aidl serviceName
disabled
oneshot

這些選項的用途如下:

  • interface aidl serviceName:允許 servicemanager 尋找服務。如果服務使用多個介面,請分行宣告每個介面。這些名稱必須是 servicemanager 預期的名稱,且可能與程序名稱不同。
  • disabled:防止服務在啟動時自動啟動。
  • oneshot:防止服務在每次停止時自動重新啟動。

詳情請參閱 Android 開放原始碼計畫中的 Android 外語言讀我

例如:

註冊服務

系統會透過 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