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)
。