大家在Android开发的时候一定用到Android系统Property值的设置,在需要的时候添加我们自己的Property值。不过大多数的时候我们只是把它当做一个系统全局变量作为判断我们自己程序运行分支的标志,其实它还有更重要的作用。
在Android系统开发的时候我们常常需要抓取Kernel Log来分析问题,本文就以一个抓取log的工具包report为例,编译出的可执行文件位于system/bin下面。
那么如何启动这个可执行文件呢? 我们在Java程序中执行系统函数
SystemProperties.set(GlobleValues.KMSG_ENABLE, "1");
GlobleValues.KMSG_ENABLE是自己定义String persist.sys.kmsg.enable的一个宏,这个函数的作用就是把persist.sys.kmsg.enable设置为1.
persist.sys.kmsg.enable不仅是report 的运行状态标志,同时在init进程作为一个action的触发条件。
在init进程启动property_service的时候,会执行
fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0, NULL);
listen(fd, 8);
来创建服务端的socket并监听。
当调用SystemProperties.set的时候,通过JNI调用__system_property_set方法,会通过socket向property service发送消息。由于Property Service 是运行在init进程,init的main函数有个无限for循环,会执行handle_property_set_fd()设置property值。
在init进程开始的时候,会把action添加到预备执行队列中,每一个action都有一个触发条件,类似于
queue_builtin_action(keychord_init_action, "keychord_init");
前面是事件后面是触发条件。执行
init_parse_config_file("/init.rc");
读取init.rc文件中我们定义的Service和action,根据init.rc的语法,一行一行的读取。
case K_on:
state->context = parse_action(state, nargs, args);
if (state->context) {
state->parse_line = parse_line_action;
return;
}
break;
比如读到on property:persist.sys.kmsg.enable=1,就会执行list_add_tail添加到预备执行队列。在设置persist.sys.kmsg.enable=1的时候会触发start kernel_report这个action,从而启动kernel_report这个Service。效果等同于我们在终端执行/system/bin/report –k这行命令,从而启动report这个服务。