從 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 Language 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
之前呼叫它。
範例: apex 服務