Android Zygote系统进程启动过程分析(Android N)

发布时间 : 星期三 文章Android Zygote系统进程启动过程分析(Android N)更新完毕开始阅读

Android Zygote系统进程启动过程分析

(Android N)

在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,因为Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的,在系统启动脚本system/core/rootdir/init.rc文件中,我们可以看到启动Zygote进程的脚本命令:

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 import /init.${ro.zygote}.rc

从上面的代码可以看出,在system/core/rootdir目录下系统不止一个zygote*.rc文件

每个文件里的启动zygote方式差不多,下面就以init.zygote64_32.rc为例看下里面的代码

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main

socket zygote stream 660 root system

onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd

writepid /dev/cpuset/foreground/tasks

service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary class main

socket zygote_secondary stream 660 root system onrestart restart zygote

writepid /dev/cpuset/foreground/tasks

看到上面的代码估计你也能猜出来另外三个zygote*.rc是怎样的,具体选择哪个文件和编译时定义的ro.zygote值有关。前面的关键字service告诉init进程创建一个名为\的进程,这个

zygote进程要执行的程序是/system/bin/app_process64,后面是要传给app_process64的参数。

接下来的\main\表示执行system/bin/app_process64后调用main方法,socket关键字表示这个zygote进程需要一个名称为\的socket资源,这样,系统启动后,我们就可以

在/dev/socket目录下看到有一个名为zygote的文件,onrestart关键字表示这个zygote进程重启时需要执行的命令,最后一个writepid关键字表示需要重写系统pid。

通过上面我们知道Zygote进程要执行的程序便是app_process64了,它位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。(app_process64 or app_process32 都是通过

frameworks/base/cmds/app_process编译出来的,只是由编译环境来决定生成那个文件),在分析zygote进程启动之前,来看看它启动的时序图

下面就看看从app_process64到Zygote启动具体流程:

1、在app_main.cpp的main函数中利用AndroidRuntime启动Zygote

[java] view plain copy 在CODE上查看代码片派生到我的代码片 int main(int argc, char* const argv[]) {

if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {

// Older kernels don't understand PR_SET_NO_NEW_PRIVS and return // EINVAL. Don't die on such kernels.

if (errno != EINVAL) {

LOG_ALWAYS_FATAL(\failed: strerror(errno));

return 12; } }

AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); // Process command line arguments // ignore argv[0] argc--; argv++;

// Everything up to '--' or first non '-' arg goes to the vm. //

// The first argument after the VM args is the \ // is currently unused. //

// After the parent dir, we expect one or more the following internal // arguments : //

// --zygote : Start in zygote mode

// --start-system-server : Start the system server.

// --application : Start in application (stand alone, non zygote) mode. // --nice-name : The nice name for this process. //

// For non zygote starts, these arguments will be followed by // the main class name. All remaining arguments are passed to // the main method of this class. //

// For zygote starts, all remaining arguments are passed to the zygote. // main function. //

// Note that we must copy argument string values since we will rewrite the // entire argument block when we apply the nice name to argv0.

int i;

for (i = 0; i < argc; i++) { if (argv[i][0] != '-') { break; }

if (argv[i][1] == '-' && argv[i][2] == 0) { ++i; // Skip --. break;

%s\

}

runtime.addOption(strdup(argv[i])); }

// Parse runtime arguments. Stop at first unrecognized option. bool zygote = false;

bool startSystemServer = false; bool application = false; String8 niceName; String8 className;

++i; // Skip unused \ while (i < argc) {

const char* arg = argv[i++];

if (strcmp(arg, \ zygote = true;

niceName = ZYGOTE_NICE_NAME;

} else if (strcmp(arg, \ startSystemServer = true;

} else if (strcmp(arg, \ application = true;

} else if (strncmp(arg, \ niceName.setTo(arg + 12);

} else if (strncmp(arg, \ className.setTo(arg); break; } else { --i; break; } }

Vector args;

if (!className.isEmpty()) {

// We're not in zygote mode, the only argument we need to pass // to RuntimeInit is the application argument. //

// The Remainder of args get passed to startup class main(). Make // copies of them before we overwrite them with the process name. args.add(application ? String8(\ runtime.setClassNameAndArgs(className, argc - i, argv + i); } else {

// We're in zygote mode. maybeCreateDalvikCache();

联系合同范文客服:xxxxx#qq.com(#替换为@)