系统服务架构
Android系统服务架构遵循 本地客户端/服务端 通信模式, Binder机制在IOS的 "Mach Message"信息传递机制。servicemanager在IOS中类比launchd进程(同时扮演Linux中PID为1的init进程)
Tips
- Binder IPC不能超过4M
- Binder不能映射具有写权限的内存区域
Binder机制
- Binder是Android的一种IPC机制
- 提供了RPC(远程过程调用)功能
RPC属于IPC,RPC为跨进程调用方法,隐藏实现细节。而IPC还包含 共享内存、互斥锁等形式。
Binder模块
- Client
- IPC的发起方
- Service
- IPC的相应方(服务器)
- ServiceManager
- 特殊的Service(给Client提供查询Service的功能)
- 句柄为0
- 提供辅助管理
- Service的一种
- Binder驱动程序 (内核空间)
- 核心组件
- 这4个组成模块分别运行在不同的进程,他们的调用也是IPC,也是通过Binder机制来完成
Client & Service
顾名思义,就是我们的Client、Service的进程。
ServiceManager服务
- 由init进程扫描init.rc启动的二进制可执行文件
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
- Binder进行IPC时的ContextManager: 通过service的名称,返回binder的句柄,使Client进行IPC
- 其自身句柄为0
- 在Shell,Native和Java层都有获取ServiceManager的方法
//Shell: service service_name method_name method_param
adb shell service call phone ***
//Native
sp<IServiceManager> defaultServiceManager()
//Java
android.os.ServiceManagerNative
android.os.ServiceManager
Context.getSystemService
- 代码 frameworks/base/cmds/servicemanager 目录下的binder.h, binder.c, service_manager.c
- service_manager main方法入口
- 调用binder_open,打开binder设备文件,获取/dev/binder描述符
- 调用binder_become_context_manager 通知binder驱动程序,自己是binder的上下文管理者(守护进程),服务索引值为0
- 调动binder_loopde无穷循环
- 进入阻塞状态,直到/dev/binder 中产生transaction(也就是Client端请求:addService、checkService和listServices),调用svcmgr_handler回调函数处理
system_server进程
- 由Java编写,必要时JNI,运行在虚拟机中
- 由init.rc forck出的Zygote进程,由–start-system-server调用方法,forck出的system_server进程
// /init.rc
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
- 容器进程,期内包含绝大多数系统服务 AMS、PMS
- 系统服务以线程的形式存在
- 创建完service的线程,主线程进入无限循环
- 不断轮询(特殊是binder句柄),以获取、分发信息 到指定小区。
Binder驱动
- 源代码 kernel/common/drivers/staging/android
- /dev/binder (mis device、杂项文件、设备文件),文件由驱动程序模块初始化时创建
- binder驱动注册的操作命令(调用这些IO API,会调用驱动注册的方法)
- 进程虚拟地址空间、内存虚拟地址空间 进行映射,这样 进程和内核之间可以减少一次 内存拷贝(提高效率)