Android4.4 Framework分析——Zygote进程的启动过程
Android启动过程中的第一个进程init。在启动过程中会启动两个关键的系统服务进程ServiceManager和Zygote。
本文要介绍的就是Zygote进程的启动,Zygote俗称孵化器,专门用于生产(启动)新的进程。Zygote是在Init.rc(aosp/system/core/rootdir)里描写叙述并由init进程启动的。相关代码例如以下:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
init.rc文件的语法描写叙述能够參考aosp/system/core/init/readme.txt。
zygote的path路径为/system/bin/app_process,-Xzygote /system/bin --zygote --start-system-server是它的參数。所属class是main,同属同一个class的进程会同一时候启动或者停止。会启动一个socket名为zygote,重新启动时将做四个操作。
以下是Zygote进程启动的大致时序图:
Android启动过程中,init进程使用aosp/system/core/init/Init_parser.c解析init.rc脚本文件。
step1。循环启动init.rc文件描写叙述的全部状态不为SVC_DISABLED的service,fork()新进程。
step2,启动Zygote,运行app_main.cpp的main()方法,
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
const char* parentDir = NULL;
const char* niceName = NULL;
const char* className = NULL;
while (i < argc) {//main的參数匹配
const char* arg = argv[i++];
if (!parentDir) {
parentDir = arg;
} else if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = "zygote";
} 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 = arg + 12;
} else {
className = arg;
break;
}
} if (niceName && *niceName) {
setArgv0(argv0, niceName);
set_process_name(niceName);
} runtime.mParentDir = parentDir; if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer ? "start-system-server" : "");
} else if (className) {
......
} else {
......
}
step3,启动AppRuntime,AppRuntime继承自AndroidRuntime,这里须要做的事情有:
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env) != 0) {//step4,创建JVM
return;
}
onVmCreated(env); /*
* Register android functions.
*/
if (startReg(env) < 0) {//step6,在JVM中注冊android本地方法
ALOGE("Unable to register all android natives\n");
return;
}
step7~step8。启动ZygoteInit的main()方法,传入一个字符串数组,strArray[0]="com.android.internal.os.ZygoteInit",strArray[1] = "start-system-server"。
step9,registerZygoteSocket()注冊服务端socket。这个socket就是前面提到的zygote,在init进程解析init.rc时创建。
public static void main(String argv[]) {
try {
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
registerZygoteSocket();
.......
preload();
.......
// Do an initial gc to clean up after startup
gc();
......
if (argv[1].equals("start-system-server")) {
startSystemServer();//step11
} else if (!argv[1].equals("")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
runSelectLoop();
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
step11,開始启动SystemServer进程,系统启动的关键进程。
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
......
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null; int pid; try {
....... /* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
} /* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);//step12
} return true;
}
Zygote.forkSystemServer()中会fork出一个新进程。是即将启动的SystemServer进程,是Zygote的子进程。
假设成功fork出新的子进程。这里将会返回两次。一次返回Zygote的pid,值大于0。这里返回运行step29。进入loop,等待ActivityManagerService调用startProcessLocked()启动新的进程,这个过程參考Android4.4
framework分析——startService的创建过程的step12~step35;还有一次返回SystemServer的进程id,等于0,将运行step12~step28。
參考:
http://blog.csdn.net/luoshengyang/article/details/6768304
www.cnblogs.com/bastard/archive/2012/08/28/2660389.html
右键复制图片地址。在浏览器中打开就可以查看大图。
未完待续,有不正确的地方。请指正。
Android4.4 Framework分析——Zygote进程的启动过程的更多相关文章
- Zygote和System进程的启动过程
##init脚本的启动 +------------+ +-------+ +-----------+ |Linux Kernel+--> |init.rc+-> |app_process| ...
- Zygote和System进程的启动过程、Android应用进程启动过程
1.基本过程 init脚本的启动Zygote Zygote进程的启动 System进程的启动 Android应用进程启动过程 2.init脚本的启动 +------------+ +-------+ ...
- Android 儿子Activity在启动过程中的流程组件 && 儿子Activity在一个新的进程组件启动过程
1.儿子Activity在启动过程中的流程组件 在Android Activity启动过程http://blog.csdn.net/jltxgcy/article/details/35984557一文 ...
- 跟踪分析Linux内核的启动过程--实验报告 分析 及知识重点
跟踪分析Linux内核的启动过程 攥写人:杨光 学号:20135233 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.stud ...
- 20135202闫佳歆--week3 跟踪分析Linux内核的启动过程--实验及总结
实验三:跟踪分析Linux内核的启动过程 一.调试步骤如下: 使用gdb跟踪调试内核 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd r ...
- 跟踪分析Linux内核的启动过程小解
跟踪分析Linux内核的启动过程 “20135224陈实 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029 ...
- 实验三:跟踪分析Linux内核的启动过程
实验三:跟踪分析Linux内核的启动过程 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.16 ...
- 20135239 益西拉姆 linux内核分析 跟踪分析Linux内核的启动过程
回顾 1.中断上下文的切换——保存现场&恢复现场 本节主要课程内容 Linux内核源代码简介 1.打开内核源代码页面 arch/目录:支持不同CPU的源代码:其中的X86是重点 init/目录 ...
- Linux内核分析第三周学习博客——跟踪分析Linux内核的启动过程
Linux内核分析第三周学习博客--跟踪分析Linux内核的启动过程 实验过程截图: 过程分析: 在Linux内核的启动过程中,一共经历了start_kernel,rest_init,kernel_t ...
随机推荐
- ANDROID 中设计模式的採用--创建型模式
所谓模式就是在某一情景下解决某个问题的固定解决方式. 全部的创建型模式都是用作对象的创建或实例化的解决方式. 1 简单工厂模式 创建对象的最简单方法是使用new来创建一个对象,假设仅仅创建一种固 ...
- VirtualBox集群建立和网络配置
安装 1. 安装 安装Oracle VM VirtualBox之后,新建一个虚拟机,制定好内存等信息,开始安装操作系统,这里安装ubuntu-12.04.2-desktop-i386版本. 2. 拷贝 ...
- setjmp和longjmp函数使用详解
源地址:http://blog.csdn.net/zhuanshenweiliu/article/details/41961975 非局部跳转语句---setjmp和longjmp函数.非局部指的是, ...
- Html中隐藏a标签
<div><a href="#"><span style="visibility:hidden">我的</span&g ...
- easy_install MySQL-python
python - Why can't easy_install find MySQLdb? - Stack Overflow easy_install MySQL-python
- hdu 2842 Chinese Rings
点击打开hdu2842 思路: 矩阵快速幂 分析: 1 题目的意思是给定n个环,和一些规则要把所有的环全部拆下最少需要的步数 2 题目规定如果要拆第n个环,那么第n-1个要挂着,n-2环要被拆下.那么 ...
- [置顶] iframe使用总结(实战)
说在前面的话,iframe是可以做很多事情的. 例如: a>通过iframe实现跨域; b>使用iframe解决IE6下select遮挡不住的问题 c>通过iframe解决Ajax的 ...
- java多线程:ReentrantReadWriteLock读写锁使用
Lock比传统的线程模型synchronized更多的面向对象的方式.锁和生活似,应该是一个对象.两个线程运行的代码片段要实现同步相互排斥的效果.它们必须用同一个Lock对象. 读写锁:分为读锁和写锁 ...
- C++--allocator类的使用
C++为我们提供了安全的内存空间申请方式与释放方式,可是new与delete表达式却是把空间的分配回收与对象的构建销毁紧紧的关联在一起.实际上,作为与C语言兼容的语言,C++也为我们提供了更加底层的内 ...
- 一个有趣的swap函数
C语言版: void swap (int a, int b) { a = a ^ b; b = a ^ b; a = a ^ b; } 原理: a ^ a == 0 0 ^ b == b 异或:同则为 ...