Android framework的Zygote源码分析
init.rc
在Android系统中,zygote是一个native进程,是Android系统上所有应用进程的父进程,我们系统上app的进程都是由这个zygote分裂出来的。zygote则是由Linux系统用户空间的第一个进程——init进程,通过fork的方式创建的。
zygote进程做了两个重要的事情:
1. 不断接收其它进程的信号,随时创建子进程(即app进程)
2. 创建了嫡长子 —— system_server进程
路径 system/core/rootdir/init.zygote32.rc,32位进程,64位进程,
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
service 标记这是一个服务,
zygote 服务名字
/system/bin/app_process -Xzygote 从哪启动app_process 是一个二进制文件,
–zygote --start-system-server 是参数,入参
大概意思是app_process 运行这个二进制文件,然后会携带后面的参数。
这是个二进制文件,Android中生成二进制文件一般是Android.mk或者Android.bp
找一下
grep “app_process” ./ -rn
这个二进制文件运行起来就会执行main方法并且传递携带的参数
argc–;
argv++;
参数数量
遍历参数, zygote = true;startSystemServer = true;都设置为true
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
这里开启start
AndroidRuntime.cpp的路径为/frameworks/base/core/jni/AndroidRuntime.cpp
启动一个java虚拟机
/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
注册jni方法
开启VM
char* AndroidRuntime::toSlashClassName(const char* className)
{
char* result = strdup(className);
for (char* cp = result; *cp != '\0'; cp++) {
if (*cp == '.') {
*cp = '/';
}
}
return result;
}
这个className就是我们这里传递过去的
获取class的main方法,如果存在就调用main方法
到这里就zggote就已经从C++层调用到了java层的。
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
预加载
加载系统的类,类来自哪里呢?
文件路径
find -name preloaded-classes
都是Android里面核心的一些类。被zygote进行预加载了,
注册了SocketServer,对系统的资源进行预加载。
linux的fork
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int pid;
//获取进程号。
printf("main current process pid == %d \n",getpid());
//系统调用函数fork()
pid=fork();
//如果fork成功了,就会有2个进程,主进程和子进程pid都是不一样的
//如果是0就运行在子进程,pid>0就是主进程。
if (pid == 0) {
printf("child process pid == %d ppid == %d \n",getpid(),getppid());
} else {
printf("this process current pid == %d pid = %d ppid == %d \n",getpid(),pid,getppid());
}
while(1);
return 0;
}
编译执行,主进程号是5021,fork之后有个pid5022,意思就是有2个进程执行这段代码。
创建systemServer
Zygote.java
jni方法
fork子进程,pid=0是子进程,
我们发现主进程就输出了一句日志,什么都没有,