Jimmy Chen

A Programmer

(原创)Android Zygote分析

1. app_process到zygote

zygote本身是一个Native应用程序,和驱动、内核均无关系,zygote是由init进行根据init.rc文件中的配置进行创建的,具体的配置代码如下:

1.1 zygote启动的init.rc文件定义

  上面的代码中可以看出,zygote的原名是app_precess,在启动的时候是通过Linux下的pctrl系统调用将自己改名为zygote,app_process对应的源文件是App_main.cpp.

1.2 App_main.cpp的main函数

2. AppRuntime分析

AppRuntime类的声明和实现都在App_main.cpp中,它是从AndroidRuntime类派生出来的,代码如下:

2.1 AndroidRuntime.cpp的start函数

  上述内容都是在Native层运行的,但是在调用ZygoteInit的main方法后,程序便会进入到Java的世界里面,下面来看看上面没有具体解释道的startVm和startReg方法。

2.2 AndroidRuntime.cpp的startVm函数

接下来看startReg函数:

2.3 AndroidRuntime.cpp的startReg函数

  androidSetCreateThreadFunc代码如下,非常简单,只是将gCreateThreadFn指向javaCreateThreadEtc

  register_jni_procs则是简单的封装,调用数组元素的MProc函数

其中gRegJNI定义如下,包含的是要注册到JNI中的函数

REG_JNI是一个宏,定义如下:

当调用array[i].mProc(env)就相当于调用相应的函数

3. Java World

上面分析到,在AndroidRuntime.cpp的start函数的最后调用CallStaticVoidMethod方法,该方法会调用到com.android.internal.os.ZygoteInit的main函数。

3.1 ZygoteInit.java的main函数

3.2 ZygoteInit.java的registerZygoteSocket函数

3.3 ZygoteInit.java的preload函数

3.4 ZygoteInit.java的startSystemServer

Zygeto进行fork后,分裂出一个system_server进程,这里主要介绍Zygote,system_server内容后面再介绍

3.5 ZygoteInit.java的runSelectLoop函数

runSelectLoop的主体是一个死循环,它将用作zygote的守护体存在

3.6 ZygoteInit.java的runOnce函数

代码如下,省略了大部分内容

3.7 Zygote.java的forkAndSpecialize函数

  forkAndSpecialize函数实在“孵化”的同时将新创建的进程转换为目标Android应用程序。函数forkAndSpecialize包含三个步骤,分别是preFork、nativeForkAndSpecialize和postForkCommon。preFork通过JNI调用到dalvik_system_ZygoteHooks.cc中的ZygoteHooks_nativePreFork函数,在这个函数中会通过runtime->PreZygoteFork来进行前期初始化。

  函数nativeForkAndSpecialize也是一个native方法,实现在com_android_internal_os_
Zygote_nativeForkAndSpecialize中,而之后又会进一步调用到FordAndSpecializeCommon方法。在FordAndSpecializeCommon方法中会通过Linux fork调用孵化出一个新的进程,然后调用到CallStaticVoidMethod这个JNI方法来执行一些孵化后的处理,但是这里并没有进行应用程序相关的业务,真正的业务执行是在runOnce中提到的handleChildProc中,之后的内容这里就不做解释了,后续在AMS中应该会提及。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注