1.引言
深入理解Android 卷1.第三章讲解了Android系统的init过程。我在学习这章的时候前前后后看了4遍。也看了很多很多博客。最后慢慢慢慢的理解了一点,当然对细节性代码还是不懂。只知道一个大概的流程。现在记录下整个init过程。
2正题
2.1 init.rc 文件的介绍
init.rc很重要一定要搞懂。详细文章请参见这个大佬的https://www.jianshu.com/p/d08e1affd5ec。
Action的格式如下:
on <trgger> [&& <trigger>]*
<command>
<command>
<command>
...
on 关键字 后面加触发器。中间的都是command命令:
init.rc 的部分文件。init.rc文件很有顺序的:按照section执行到先后顺序排布的。其中重要的步骤是:
on-early init
on init
on late-init
on boot
为什么会提到这些。因为在init.cpp中会对这四个步骤。调用代码进行执行。
2.2 解析init.rc的过程
init_parser.cpp文件:
当遇到section的时候就会走case T_NEWLINE。 进而执行到parse_new_section();
parse_new_section()
我们来看下解析case k_on的情况:
分析parse_line_action
list_add_tail 是一个双向链表。都command都添加到list的尾部(tail)。之后依次执行
on early-init ,init,late-init,boot,调用代码 如下所示:
总结init.rc过程:
通过parse_new_section ->parse_line_action 最终将command都添加进双向列表。然后在init.cpp中依次执行 以下section中的caommand 。
on early-init
init
late-init
boot
现在有一个问题:command是怎么去执行的?
答案: 每个command 都对应一个 执行函数。这样知道了command 就了执行函数。这个执行函数在keywords.cpp 里面。
3.启动zygote线程
在on boot section 下面有一个 class_start core 的命令。根据keywords class_start 对应的函数就是do_class_start().
service_start_if_not_disabled() 方法:
这个service_start() 是在 init.cpp中的。这个方法通过条用 fork()方法 产生zygote方法。
4 属性服务器工作流程
属性服务器也不是特别了解,我就按照书上,博客上走一遍流程,加深影响。Android 6.0 和4.4的 代码差别存在。好多4.4上提供的代码参考,6.0上都没得。
属性服务就像window的注册表采用key-value的形式保存数据。所以万变不离其宗,跟踪代码总会发现set(key,value)的字样。
按照init.cpp中对property_service流程进行分析:
property_init() ----->start_property_service
property_init():
初始化属性服务,主要是初始化内存区域,并且该内存区域是内存共享的。想来也对,就像在Android中使用sh,肯定要创建一块内存区域,不然怎么去保存数据呢?
start_property_service
create_socket创建了一个专门用来接收请求的socket。很显然,其他进程是能通过ipc 与此socket进行通信的。
该方法目的就是将handler_property_set_fd 与socket绑定起来。register_epoll_handler的方法在init.cpp
。
这样当socket接受到一个请求,handle_property_set_fd就负责处理请求:
handle_property_set_fd:找到这段代码
property_set(key,value)最终调用 的是:
注意是property_service中的 property_set()方法。
property_set_iml(name,value)就是对文件中的key.value进行保存。
总结:上述 属性服务器算是启动完毕,工作流程如上所示。那么问题来了客户端是怎么调用呢?
4.1 客户端与属性服务器通信
客户端与服务器进行交互是通过调用如下代码:
_system_property_set(key,value) 代码:
通过socket与属性服务器接受的socket进行连接,发送消息,接受端的socket收到之后就会执行handler_proerty_set_fd().然后写入到文件中。