Service Manager(SM):大管家。管理系统服务的 Ibinder。
1 如何启动 service_manager 服务
SM注册:
1 binder_open(): 打开驱动(设置大小128K),内存映射
2 binder_become_context_manager(): 设置 SM 为大管家 --- sm 作用:为了管理系统服务
1 创建 binder_node 结构体对象
2 proc --指向--> binder_node
3 创建 work 和 todo 队列 ---》 类似 messageQueue
3 binder_loop(): BC_ENTER_LOOPER 命令
1 写入状态 Loop
2 去读数据:binder_thread_read: ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc,thread)); 进入等待。
binder_become_context_manager(): 设置 SM 为大管家;binder_loop(): 循环监听
binder_ioctl 里的 binder_ioctl_set_ctx_mgr() :创建 binder_node 结构体对象,把 proc 指向 binder_node ,创建 work 和 todo 队列
Binder_loop: binder_write() binder_reade() binder_thread_write() binder_thread_read()
2 如何获取 service_manager服务
SM 获取:
需要获取 SM 的情况:1、注册服务到SM; 2、通过 SM 去获取服务--java
1 ProcessState::self() -> getContextObject(NULL)
1 ProcessState::self()
1. 打开驱动:binder
2. 设置线程最大数目:15个
3. mmap --设置共享内存大小(1M - 8K) 普通服务的大小
2 getContextObject
1. 创建一个 BpBinder --相当于客户端对象
2 interface_cast
1 new BpServiceManager(new BpBinder)
2 remote.transact --> 远程调用(跨进程)
3 remote == BpBinder
3 java 层 ---serviceManager.addService
1 new ServiceManagerProxy(new BinderProxy)
2 mRemote == BinderProxy
3 BinderProxy.mObject == BpBinder
4 mRemote.transact = BpBinder.transact (调用transact 就跨进程)
3 详解 AIDL 生成 Java 类
AIDL 帮我们处理 Binder 中繁琐、复杂的操作。
1、AsInterface:区分是在当前进程,还是跨进程。
2、proxy在调用时:1 打包;2 检测;3 跨进程(跨进程时,当前客户端线程要挂起 ---同步情况)。
3 stub(服务端):onTransact(),通过 code 参数进入第二个 case(下图圈出)里,执行 this.addPerson()方法,就能调用到服务端正真的方法。