1.作用
- ServiceManager是BinderIPC機制的組成部分
- 註冊服務
- 檢索服務
Binder IPC機制定義了四種角色: Service,Client,ServiceManager以及Binder驅動。這四個角色的關係和互聯網類似:Service相當於服務器,Client相當於客戶端,ServiceManager相當於DNS,Binder驅動相當於路由器。
Binder架構圖如下所示:
2.啓動
在開機時,由init進程啓動
init.rc
service servicemanager /system/bin/servicemanager
啓動後進入循環監視
service_manager.c
binder_loop(bs, svcmgr_handler)
3. 註冊服務
- 註冊服務是指將service註冊到ServiceManager中,保存在全局變量service_list中。
- 註冊服務過程中也是在開機時由init進程啓動zygote進程,由zygote進程啓動system_serviewr進程,然後在system_server進程中用addService在一個個註冊並啓動系統服務。
- addService
public static void addService(String name, IBinder service)
參數 name:要註冊的服務名稱
參數 service:要註冊的服務
SystemServer.java
Slog.i(TAG, "Scheduling Policy");
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
mSystemServiceManager.startService(TelecomLoaderService.class);
Slog.i(TAG, "Telephony Registry");
telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
Slog.i(TAG, "Entropy Mixer");
entropyMixer = new EntropyMixer(context);
mContentResolver = context.getContentResolver();
Slog.i(TAG, "Camera Service");
mSystemServiceManager.startService(CameraService.class);
// The AccountManager must come before the ContentService
try {
// TODO: seems like this should be disable-able, but req'd by ContentService
Slog.i(TAG, "Account Manager");
accountManager = new AccountManagerService(context);
ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting Account Manager", e);
}
註冊成功後的service,可以通過service list命令查看
130|root@local:/ # service list
Found 135 services:
0 media.widi.uibc: [intel.widi.IUibcServer]
1 cmcc_conference: [com.grandstream.convergentconference.service.IConferenceService]
2 gs_service_internal_proxy: [com.gs.service.IGsServiceInternalProxy]
3 gs_service_ucm: [com.gs.ucm.IUcmManager]
4 gs_service_ldap: [com.gs.ldap.manager.ILDAPServiceManager]
5 gs_service_guest_login: [com.gs.api.guest.IGuestLoginManager]
4.檢索服務
1.檢索服務是值當客戶端需要與service進行通信時,首先要通過ServiceManager檢索service的Binder節點,並返回給客戶端,此時客戶端就知道用哪個Binder進行通信了。
2.客戶端與ServiceManager之間也是通過Binder通訊的,但客戶端與ServiceManager通訊之前不需要查找ServiceManager的Binder編號。因爲ServiceManager的Binder編號固定爲0.當客戶端需要通過ServiceManager查找所需服務的Binder節點時,直接通過0號Binder。
3. public static IBinder checkService(String name)
參數name:要檢索的服務名稱
返回值:和name服務通訊的Binder節點。
IBinder binder = ServiceManager.getService("vibrator")
5. 訪問服務
- 訪問服務指的是客戶端通過檢查到的Binder節點,調用服務進程中的方法。
- Binder IPC,這種進程通訊機制,有個非常明顯的好處,這種機制使得客戶端進程調用遠程服務進程的方法時,就像調用本地的方法一樣輕鬆簡單。
不過在調用方法前,還需要將Binder節點強制類型轉換成爲服務代理類型。
例如:
IVibratorService mService = IVibratorService.Stub.asInterface(Binder);
mService.viratePattern(pattern, repeat, mToken);
Android 基本Binder IPC如下所示:
Android ServiceManager的 Binder IPC如下所示
如圖上圖,基本的Binder IPC與ServiceManager的Binder IPC略有不同,由Binder Driver返回的RPC
數據,基本的Binder IPC是由服務Stub處理;Binder Driver盡心循環監視,當有數據到來時,觸發處理函數svcmgr_handler.請參考代碼: service_manager.c binder_loop(bs, svcmgr_handler)
。