自 Android 11 起,在系統分區中執行的原生 AIDL 服務可視需要動態啟動及停止。動態服務會在首次要求時啟動,並在不再使用時自動停止。
可動態執行的服務
這項功能僅適用於原生服務,也就是生命週期可由 init
和 servicemanager
控制的服務。應用程式套件中的服務不受支援,應改用繫結服務。
動態關機功能會關閉服務執行的程序。如果同一個程序中有多項服務,則所有服務都必須以動態方式註冊,才能與這項功能相容。當所有服務都未使用時,該程序就會關閉。
設定服務的初始化 .rc 檔案
如要動態執行服務,請在服務的初始化 .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
之前呼叫。
示例:apexservice