文章目录
- [Android framework的Zygote源码分析](#Android framework的Zygote源码分析)
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位进程,
![](https://img-blog.csdnimg.cn/direct/49ddc578c7cf485fa618d9b6abeeca8d.png)
![](https://img-blog.csdnimg.cn/direct/e3ede68938f44abf91c8675e2fa89f5a.png)
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
![](https://img-blog.csdnimg.cn/direct/fc47ed02571f4cb2957b74c1db93ae0c.png)
![](https://img-blog.csdnimg.cn/direct/970fc977b1c94dbd986740c40fe10abd.png)
这个二进制文件运行起来就会执行main方法并且传递携带的参数
![](https://img-blog.csdnimg.cn/direct/ebfcbabb655e48b4a3263d7629c16255.png)
argc--;
argv++;
参数数量
遍历参数, zygote = true;startSystemServer = true;都设置为true
c++
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
![](https://img-blog.csdnimg.cn/direct/edaecbf58fb4405dabd9ad82db1b0209.png)
启动一个java虚拟机
![](https://img-blog.csdnimg.cn/direct/6c5489476a8d42a8aa79a517aed346ff.png)
c++
/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
注册jni方法
![](https://img-blog.csdnimg.cn/direct/e8f135feee204ddca8559ffa70f6d6d9.png)
开启VM
![](https://img-blog.csdnimg.cn/direct/d1bf8334ac0d479b819b396702cf14b5.png)
c++
char* AndroidRuntime::toSlashClassName(const char* className)
{
char* result = strdup(className);
for (char* cp = result; *cp != '\0'; cp++) {
if (*cp == '.') {
*cp = '/';
}
}
return result;
}
这个className就是我们这里传递过去的
![](https://img-blog.csdnimg.cn/direct/60120ba2f3fe422598ed9f6200459a6f.png)
获取class的main方法,如果存在就调用main方法
![](https://img-blog.csdnimg.cn/direct/78cede78d36f4027acf4e62ae2633df4.png)
到这里就zggote就已经从C++层调用到了java层的。
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
预加载
![](https://img-blog.csdnimg.cn/direct/0d68d2dcb2a04283b4e4c635ca8748fa.png)
加载系统的类,类来自哪里呢?
![](https://img-blog.csdnimg.cn/direct/5658bc58cf58452695c77ebd9b8de3c3.png)
文件路径
![](https://img-blog.csdnimg.cn/direct/61e9fffc0e0448f4b742494483b5faff.png)
![](https://img-blog.csdnimg.cn/direct/88556c8aa5ab4413909a3c74105c4923.png)
find -name preloaded-classes
![](https://img-blog.csdnimg.cn/direct/1caa37b3a80f480db651558b312ff329.png)
![](https://img-blog.csdnimg.cn/direct/0d5c30ec72dd42c9b12a151d6a10e317.png)
都是Android里面核心的一些类。被zygote进行预加载了,
注册了SocketServer,对系统的资源进行预加载。
linux的fork
c++
#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;
}
![](https://img-blog.csdnimg.cn/direct/f01b0829efa94afc906c08a1d1e24f32.png)
编译执行,主进程号是5021,fork之后有个pid5022,意思就是有2个进程执行这段代码。
![](https://img-blog.csdnimg.cn/direct/22d5da175053425db8538581695789ac.png)
创建systemServer
![](https://img-blog.csdnimg.cn/direct/5682aa721ec74df289b2e722afaa5617.png)
![](https://img-blog.csdnimg.cn/direct/2f1bbe2926d84ba9918665e6b5e336fc.png)
Zygote.java
![](https://img-blog.csdnimg.cn/direct/b9ac7b838db14356b32098ed4b38e96f.png)
jni方法
![](https://img-blog.csdnimg.cn/direct/884e30aa31864bf0ac81abf11149b003.png)
fork子进程,pid=0是子进程,
![](https://img-blog.csdnimg.cn/direct/f021911fe08a489da9032acff9cbeba1.png)
我们发现主进程就输出了一句日志,什么都没有,
![](https://img-blog.csdnimg.cn/direct/8350e60454174d928ad8d4520ca8d03d.png)