Zygote启动的命令行定义在init.zygote.rc的zygote服务中。
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 |
由于有--zygote参数,app_process启动后进入com.android.internal.os.ZygoteInit的main方法中的初始化过程。
流程
主流程
- ZygoteInit的main方法
推算下来main参数为:
ZygoteInit [start-system-server] <args> |
- registerZygoteSocket()
- System.getenv()【从环境变量获取服务套接字值,ANDROID_SOCKET_zygote】
- new LocalServerSocket【标准UNIX侦听套接字】
- preload()
- preloadClasses()
- preloadResources()
- preloadOpenGL()
- gc()
- startSystemServer()【如果有--start-system-server参数】
- Zygote.forkSystemServer()
- nativeForkSystemServer()【jni】
- ForkAndSpecializeCommon()【步骤二】
- nativeForkSystemServer()【jni】
- if (pid == 0)【子进程,步骤三】
- handleSystemServerProcess()【抛异常,不会退出】
- Zygote.forkSystemServer()
- runSelectLoop()【见流程“启动新进程”】
- closeServerSocket()
- Zygote JNI(ForkAndSpecializeCommon)
- SetSigChldHandler()
- fork()
- if (pid == 0)【子进程】
- DetachDescriptors()【用/dev/null覆盖需要关闭的描述符,描述符自身保持有效】
- EnableKeepCapabilities()【切换pid时,保持进程权限】
- prctl(PR_SET_KEEPCAPS)
- DropCapabilitiesBoundingSet()
- MountEmulatedStorage()
- SetGids()【设置用户组列表】
- setgroups()
- setresgid()【设置有效用户组id】
- setresuid()【设置有效用户id】
- SetCapabilities()
- capset()
- SetSchedulerPolicy()
- set_sched_policy(SP_DEFAULT)
- UnsetSigChldHandler()
- env->CallStaticVoidMethod()【调用Zygote.callPostForkChildHooks】
- system-server进程入口
- handleSystemServerProcess()
- closeServerSocket()
- Process.setArgV0()
- RuntimeInit.zygoteInit()
- redirectLogStreams()
- commonInit()【同上,见app_process的RuntimeInit】
- nativeZygoteInit()【调用到AndroidRuntime的onZygoteInit虚方法】
- AppRuntime::onZygoteInit()
- ProcessState::self()
- proc->startThreadPool()
- AppRuntime::onZygoteInit()
- applicationInit()
- nativeSetExitWithoutCleanup()【顶层C库直接退出,调用_exit】
- VMRuntime.getRuntime().setTargetSdkVersion()【设置sdk版本】
- invokeStaticMain()
- throw new ZygoteInit.MethodAndArgsCaller(m, argv)【抛出异常退出调用栈,ZygoteInit.main()方法处理该异常】
- 进入SystemServer的main方法
ZygoteInit.main()捕获异常MethodAndArgsCaller,调用其run方法。
- MethodAndArgsCaller.run()
- mMethod.invoke()【调用实际类的main方法】
启动新进程
- ZygoteInit的套接字服务循环(runSelectLoop)
- while (true)
- selectReadable()
- acceptCommandPeer()
- if (index == 0)
- new ZygoteConnection
- peers.add()
- else
- peers.get(index).runOnce()【步骤二】
- peers.remove()
- if (index == 0)
- ZygoteConnection启动进程
- ZygoteConnection::runOnce()
- readArgumentList()
- mSocketReader.readLine()【第一行argc】
- for i = [0, argc)【每行一个参数】
- mSocketReader.readLine()
- mSocket.getAncillaryFileDescriptors()【通过UNIX套接字传递过来的文件描述符,用于标准输入等】
- if (parsedArgs.abiListQuery)
- handleAbiListQuery()【返回ZygoteInit的参数--abi-list=的值】
- mSocketOutStream.writeInt()
- mSocketOutStream.write()
- handleAbiListQuery()【返回ZygoteInit的参数--abi-list=的值】
- if (parsedArgs.runtimeInit && parsedArgs.invokeWith)
- Libcore.os.pipe()【创建管道,子进程的子进程返回进程id】
- Zygote.forkAndSpecialize()
- nativeForkAndSpecialize()
- ForkAndSpecializeCommon()【见流程“主流程”】
- nativeForkAndSpecialize()
- if (pid == 0)【子进程】
- IoUtils.closeQuietly()【关闭ID返回管道的server端】
- handleChildProc()【子进程入口,步骤三】
- else【父进程】
- IoUtils.closeQuietly()【关闭ID返回管道的client端】
- handleParentProc()【父进程继续处理,步骤四】
- readArgumentList()
- 子进程入口(handleChildProc)
- closeSocket()
- mSocket.close()【关闭UNIX套接字连接】
- ZygoteInit.closeServerSocket()
- sServerSocket.close()【关闭UNIX侦听套接字】
- if (descriptors != null)
- ZygoteInit.reopenStdio()【native方法,复制描述符】
- foreach descriptors
- IoUtils.closeQuietly(fd)【关闭原描述符】
- if (parsedArgs.niceName)
- Process.setArgV0()【设置进程名】
- if (parsedArgs.runtimeInit)【参数--runtime-init】
- if (parsedArgs.invokeWith)
- WrapperInit.execApplication()【启动app_process】
- Zygote.execShell()【步骤五】
- WrapperInit.execApplication()【启动app_process】
- else【这是APP应用正常启动方式】
- RuntimeInit.zygoteInit()【同上,见流程“主流程”】
- if (parsedArgs.invokeWith)
- else
- 【提取第一个参数parsedArgs.remainingArgs[0]作为类名】
- if (parsedArgs.invokeWith)
- WrapperInit.execStandalone()【启动dalvikvm】
- Zygote.execShell()【步骤六】
- WrapperInit.execStandalone()【启动dalvikvm】
- else
- ClassLoader.getSystemClassLoader()【外部可以指定classpath】
- ZygoteInit.invokeStaticMain()【同RuntimeInit.invokeStaticMain】
- 加载类
- throw new ZygoteInit.MethodAndArgsCaller(m, argv)【抛异常,退回调用栈,并调用指定类的main方法,见流程“主流程”】
- 父进程继续处理(handleParentProc)
- if (pid > 0)【启动成功】
- setChildPgid()【子进程移动到请求进程的进程组中】
- ZygoteInit.setpgid()
- setChildPgid()【子进程移动到请求进程的进程组中】
- if (descriptors != null)
- foreach descriptors
- IoUtils.closeQuietly(fd)【关闭原描述符】
- foreach descriptors
- if (pipeFd)
- 等待返回实际进程id
- mSocketOutStream.writeInt()【在套接字连接上返回实际进程id】
- mSocketOutStream.writeBoolean()【在套接字连接上返回usingWrapper】
- WrapperInit的启动应用(execApplication)
命令行格式为:
<invokeWith> /system/bin/app_process /system/bin -application WrapperInit <pipeFd> <targetSdkVersion> <args> |
app_process在RuntimeInit初始化完成后,调用WrapperInit的main方法,推算下来参数为:
<pipeFd> <targetSdkVersion> <args> |
- 【写入新进程id到pipeFd】
- ZygoteInit.preload()【预加载类,资源,opengl】
- RuntimeInit.wrapperInit()
- applicationInit()【同上,见流程“主流程”】
- WrapperInit的独立程序(execStandalone)
命令行格式为:
<invokeWith> /system/bin/dalvikvm -classpath <classPath> <className> <args> |