该系列文章总纲链接:专题总纲目录 Android Framework 总纲
本章关键点总结 & 说明:
说明:思维导图是基于之前文章不断迭代的,本章内容我们关注➕"action队列" 部分即可
对于action队列初始化,这里主要针对两个关键方法进行分析,action_for_each_trigger和queue_builtin_action
1 action_for_each_trigger的实现如下:
void action_for_each_trigger(const char *trigger,void (*func)(struct action *act))
{
struct listnode *node;
struct action *act;
list_for_each(node, &action_list) {
act = node_to_item(node, struct action, alist);
if (!strcmp(act->name, trigger)) {//链表中只要和trigger同名,就执行func操作
func(act);
}
}
}
action_for_each_trigger是对此类trigger所在所有命令,都加入到actions的list中去,即所有的*.rc文件的同一个trigger都一起处理的,并且处理的流程是按照import后的顺序执行的。
注意:各个trigger的加载顺序是先加入顺序执行,尤其是要修改init.rc文件的时候,不了解这个容易因为前后依赖关系造成问题。特殊说明:在trigger命令中,实际上最后调用的也是该方法,即效果是一样的。
2 queue_builtin_action的实现如下:
oid queue_builtin_action(int (*func)(int nargs, char **args), char *name)
{
struct action *act;
struct command *cmd;
act = calloc(1, sizeof(*act));
act->name = name;
list_init(&act->commands);
list_init(&act->qlist);
cmd = calloc(1, sizeof(*cmd));
cmd->func = func;
cmd->args[0] = name;
cmd->nargs = 1;
list_add_tail(&act->commands, &cmd->clist);//将节点cmd->clist插入到队列act->commands所在链表尾部
list_add_tail(&action_list, &act->alist);//将节点act->alist后插入到队列action_list所在链表尾部
action_add_queue_tail(act);
}
继续分析action_add_queue_tail(act),实现如下:
void action_add_queue_tail(struct action *act)
{
if (list_empty(&act->qlist)) {
list_add_tail(&action_queue, &act->qlist);//将节点act->qlist节点插入到队列action_queue所在链表尾部
}
}
说明:queue_builtin_action的作用就是内建一个actions,将actions动作加入到actions list中。
3 action的执行顺序最后解析如下:
on early-init
on init #这里会执行完属性服务,接下来就可以设置属性了
on late-init #在这里会通过trigger来执行其他的action,以下均是
on early-fs
on fs
on post-fs
on post-fs-data
on firmware_mounts_complete
on early-boot
on boot