前提
1.回顾
在Android系统中,第一个启动的就是init进程,由init进程加载并解析init.rc以及init.zygote64.rc等等配置文件。来启动相应的service。Zygote就是由他启动起来的。Zygote是一个孵化器,system_server和所有的应用程序都是由他创建出来的。最初的时候Zygote进程的名称并不是Zygote而是app_process。Zygote启动后,Linux系统下的pctrl系统会调用app_process,所以把名称换成了Zygote。
2.架构
Zygote他是一个C/S架构。Zygote进程做为服务端,通过Socket的方式和其他进程进行通信。当接收到数据的时候会fork子进程,fork是不会复制父进程的内存,而是和父进程共享一个内存空间,只有需要进行内存数据修改的时候才会进行内存复制,也就是常说的读时共享,写时复制。
3.工作内容
Zygote做为一个孵化器,会提前加载一些系统资源、创建Java虚拟机、注册JNI等等,这样子进程就可以直接使用,避免重复加载。比如Zygote中的JNI函数、主题资源等等。
正文
1.Zygote的启动
在之前的init中有讲到,init解析init.rc的时候会解析service字段 并添加到serviceList中,并且执行fork对应的进程,执行程序。这些启动脚本都存放在 system/core/rootdir
目录中。
代码如下:
#解析服务 并且添加到serviceList中
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary 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
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
#遍历serviceList 调用start函数 fork进程 execv执行app_process64
on nonencrypted class_start main class_start late_start
app_process64对应代码就在/frameworks/base/cmds/app_process
目录下。对应的源文件就是app_main.cpp。
init进程启动后通过调用execv(“/system/bin/app_process64”,“-Xzygote /system/bin --zygote --start-system-server”) 执行程序,并且将参数传递给main函数。
接下来我们看看zygote的main函数做了什么?
//init传递过来的参数如下 -Xzygote /system/bin --zygote --start-system-server
int main(int argc, char* const argv[])
{
//#ifndef LOG_NDEBUG
//#ifdef NDEBUG
//#define LOG_NDEBUG 1
//#else
//#define LOG_NDEBUG 0 所以这里是true 会把参数存放到argv_String中,然后打印出来
if (!LOG_NDEBUG) {
String8 argv_String;
for (int i = 0; i < argc; ++i) {
argv_String.append(""");
argv_String.append(argv[i]);
argv_String.append("" ");
}
ALOGV("app_process main with argv: %s", argv_String.string());
}
//创建开启AppRuntime,并将参数传递给AppRuntime
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
argc--;
argv++;
bool known_command = false;
int i;
for (i = 0; i < argc; i++) {
if (known_command == true) {
runtime.addOption(strdup(argv[i]));
ALOGV("app_process main add known option '%s'", argv[i]);
known_command = false;
continue;
}
for (int j = 0;
j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
++j) {
if (strcmp(argv[i], spaced_commands[j]) == 0) {
known_command = true;
ALOGV("app_process main found known command '%s'", argv[i]);
}
}
if (argv[i][0] != '-') {//如果参数第一个字符是'-'跳出循环,Zygote传递的第一个参数是-Xzygote 所以执行到这里会跳出循环
break;
}
if (argv[i][1] == '-' && argv[i][2] == 0) {
++i; // Skip --.
break;
}
runtime.addOption(strdup(argv[i]));
ALOGV("app_process main add option '%s'", argv[i]);
}
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i;
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {//传递的参数有--zygote的就把zygote赋值为true niceName = zygote
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) { //传递的参数有start--system-server 把startSystemServer 赋值为tue表示当前进程的main是需要开启system_server的
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {//如果传递的参数包含了--application 表示当前是应用程序
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {//指定进程名
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {//application程序传递过来的className 也就是需要启动的class
className.setTo(arg);
break;
} else {
--i;
break;
}
}
Vector<String8> args;
if (!className.isEmpty()) {//如果class不为空 说明是application,但是此时我们是空的,所以我们会走下面的分支
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
if (!LOG_NDEBUG) {
String8 restOfArgs;
char* const* argv_new = argv + i;
int argc_new = argc - i;
for (int k = 0; k < argc_new; ++k) {
restOfArgs.append(""");
restOfArgs.append(argv_new[k]);
restOfArgs.append("" ");
}
ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
}
} else {//这里就是zygote启动模式
// We're in zygote mode.
maybeCreateDalvikCache();//创建Dalvik的缓存目录, data/dalvik-cache的目录
if (startSystemServer) {//如果需要运行system_server的 会添加这个参数
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
ABI_LIST_PROPERTY);
return 11;
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {//设置进程别名
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) {//注意这里之前传递的参数zygote 所以这里是true。他会调用runtime的start函数 传递com.android.internal.os.ZygoteInit 以及 init传递过来的参数 和true
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {//application模式
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
代码比较长,我总结下首先会打印日志把传递过来的参数打印出来。接着会创建AppRuntime
对象,将参数传递给AppRuntime并初始化。接着根据init传递过来的参数--zygote
把zygote
设置成true
表示是以zygote模式启动,如果需要开启system_server的会把start-system-server
也设置为true
。如果传递的是application就是以app模式启动,他就会查找对应的className,如果className部位空就会添加对应的参数。否则就是Zygote模式,在Zygote模式中会先创建Davik的缓存目录。最后调用runtime.start()
,看是以什么模式启动,如果是Zygote模式启动就会传递com.android.internal.os.ZygoteInit
和将整理的参数以及zygote 传递下去,如果是app模式就会传递com.android.internal.os.RuntimeInit
和 args以及 zygote;
2.AndroidRuntime
接下来我们需要接触两个非常重要的类AppRuntime和AndroidRuntime。这两个类是整个Android Runtime环境的接口类,
他们的关系是:
class AppRuntime : public AndroidRuntime
AppRuntime是AndroidRuntime的子类。
看看AppRuntime::start()
我们看到AppRuntime没有start函数,start函数的实现在父类AndroidRuntime
中。我们直接跳到AndroidRuntime中看看。
文件目录:/framework/base/core/jni/AndroidRuntime
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
ALOGD(">>>>>> START %s uid %d <<<<<<\n",
className != NULL ? className : "(unknown)", getuid());
static const String8 startSystemServer("start-system-server");
/*
* 'startSystemServer == true' means runtime is obsolete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
}
//获取ANDROID_ROOT 目录
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir =