《Android的设计与实现:卷I》——第3章3.4.5解析Action

    xiaoxiao2021-04-18  216

    3.4.5 解析Action

    1.parse_action

    解析Action首先从parse_action函数开始,代码如下:static void parse_action(struct parse_state state, int nargs, charargs){ struct action act; ……//省略错误处理内容 act = calloc(1, sizeof(act)); act->name = args[1]; list_init(&act->commands); /将Action的指针节点放入action_list中/ list_add_tail(&action_list, &act->alist); return act;}从parse_action函数的代码可以看出,解析Action的过程与解析Service的过程十分相似。首先给新创建的Action分配存储空间,然后将Action的指针节点放入一个action_list列表中。这里又涉及两个重要的数据类型:action结构体和action_list链表。action_list与service_list都是由list_declare宏声明,即static list_declare(action_list)。action结构体定义在/system/core/init/init.h中,代码如下:struct action { /这个指针节点所在的链表存储了所有Action的指针节点 / struct listnode alist; /这个指针节点所在的链表存储了所有即将执行的Action的指针节点/ struct listnode qlist; /这个指针节点所在的链表存储了所有要触发的Action的指针节点/ struct listnode tlist; unsigned hash; const charname; /Action对应的Command/ struct listnode commands; struct command current;};

    2.parse_line_action

    熟悉了Action的存储形式,接着分析Action的解析过程。定位到parse_line_action函数,该函数位于init_parser.c中,代码如下:static void parse_line_action(struct parse_state state, int nargs, charargs){

    struct command cmd; /通过state结构体得到当前Action的引用/ struct action *act = state->context; int (func)(int nargs, charargs); int kw, n; /依然是根据关键字匹配,不过这次匹配的是Command / kw = lookup_keyword(args[0]); n = kw_nargs(kw); ……//省略错误处理内容 cmd = malloc(sizeof(cmd) + sizeof(char) nargs); cmd->func = kw_func(kw);//获取Command对应的指令函数 cmd->nargs = nargs; memcpy(cmd->args, args, sizeof(char)nargs); /将Command加入Action的Command列表/ list_add_tail(&act->commands, &cmd->clist);

    parse_line_action函数的执行过程很清晰,要比parse_line_service简单很多。这里涉及一个重要的数据类型struct command。command结构体定义在/system/core/init/init.h中,代码如下:struct command{ / list of commands in an action / struct listnode clist; / command对应的执行函数/ int (func)(int nargs, charargs); int nargs; char args[1];};至此,init.rc的解析过程便告一段落。接下来开始分析Action和Service的执行阶段。

    相关资源:七夕情人节表白HTML源码(两款)

    最新回复(0)