1.ServiceManager
ServiceManager在init进程启动后启动,用来管理系统中的Service。
首先看一下开机过程,一般开机过程分为三个阶段:
①OS级别,由bootloader载入linux内核,内核开始初始化,并载入built-in的驱动程序,内核完成开机后,载入init进程,切换至用户空间。
②Android-level,由init进程开始,读取init.rc,Native服务启动,并启动重要的外部程序,如ServiceManager、zygote。
③Zygote-Mode,Zygote启动System Service,然后进入Zygote Mode,在Socket等候命令,随后,使用者将看到一个桌面环境,桌面环境由一个名为Launcher的应用程序负责提供。
ServiceManager是由init进程启动的,它是Binder进程间通信机制的核心组件之一,扮演着Binder进程间通信机制上下文管理者的角色,同时它还负责管理系统中的Service组件,并且向Client组件提供获取Service代理对象的服务。
ServiceManager运行在一个独立的进程中,因此Service组件和Client组件也需要通过进程间通信机制来和它进行交互,而采用的进程间通信机制也是Binder机制。这样看来ServiceManager除了是Binder进程间通信机制的上下文管理者外,还是一个特殊的Service组件。
进程间通信:
①(绿色线)系统服务首先要通过Binder驱动注册到ServiceManager中,ServiceManager有保存服务的功能。
②(红色线)Client端通过Binder驱动在ServiceManager中获取想要的服务。
③(灰色线)ServiceManager通过Binder驱动将对应的服务返回给Client端。
④(蓝色线)Client端拿到系统服务后,通过Binder驱动与Server进程进行通信,使用服务。
⑤(橙色线)Server端收到Client端的请求后,通过Binder驱动将响应结果返回给Client端。
ServiceManager是整个binder机制的守护进程,它是Server和Cilent之间沟通的桥梁。ServiceManager、Server、Cilent三者运行在不同的进程,ServiceManager在充当守护进程的同时,也在充当Server,因为当Server进程注册服务到ServiceManager时,Server是客户端,ServiceManager是服务端,当Client从ServiceManager中获取服务时,Client是客户端,ServiceManager是服务端,当建立好关系后,Client就可以和Server通信了。
2.ServiceManager的启动
所有的系统服务都需要在ServiceManager中进行注册,而ServiceManager作为一个起始的服务,是由init进程通过解析servicemanager.rc创建的(android7.0之前是解析init.rc文件)。
init进程读取了servicemanager.rc文件后就会启动servicemanager进程(init进程中创建了zygote和ServiceManager进程,而zygote进程中创建了system_server进程)。
servicemanager的入口函数在service_manager.c中:
//frameworks\native\libs\binder\ndk\service_manager.cpp
int main(int argc, char** argv){
struct binder_state *bs; //binder_state结构体,用来存储binder的三个信息
bs = binder_open(driver, 128*1024);//打开binder驱动,并申请128k字节的内存空间
...
//将自己注册为Binder机制的管理者
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
...
//启动循环,等待并处理client端发来的请求
binder_loop(bs, svcmgr_handler);
return 0;
}
在main函数中,ServiceManager的启动过程主要做了3件事情:
①调用binder_open打开驱动,并申请了128k字节大小的内存空间。
②调用binder_become_context_manager将自己注册为Binder机制的管理者。
③调用binder_loop启动循环,等待并处理Client端发来的请求。
(1)binder_open
binder_open方法的主要功能是打开Binder的驱动文件,并将文件进行mmap映射&#x