Android 源码分析 - 系统 - zygote

        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>

  1. registerZygoteSocket()
    1. System.getenv()【从环境变量获取服务套接字值,ANDROID_SOCKET_zygote】
    2. new LocalServerSocket【标准UNIX侦听套接字】
  2. preload()
    1. preloadClasses()
    2. preloadResources()
    3. preloadOpenGL()
  3. gc()
  4. startSystemServer()【如果有--start-system-server参数】
    1. Zygote.forkSystemServer()
      1. nativeForkSystemServer()【jni】
        1. ForkAndSpecializeCommon()【步骤二】
    2. if (pid == 0)【子进程,步骤三】
      1. handleSystemServerProcess()【抛异常,不会退出】
  5. runSelectLoop()【见流程“启动新进程”】
  6. closeServerSocket()
  • Zygote JNI(ForkAndSpecializeCommon)
  1. SetSigChldHandler()
  2. fork()
  3. if (pid == 0)【子进程】
    1. DetachDescriptors()【用/dev/null覆盖需要关闭的描述符,描述符自身保持有效】
    2. EnableKeepCapabilities()【切换pid时,保持进程权限】
      1. prctl(PR_SET_KEEPCAPS)
    3. DropCapabilitiesBoundingSet()
    4. MountEmulatedStorage()
    5. SetGids()【设置用户组列表】
      1. setgroups()
    6. setresgid()【设置有效用户组id】
    7. setresuid()【设置有效用户id】
    8. SetCapabilities()
      1. capset()
    9. SetSchedulerPolicy()
      1. set_sched_policy(SP_DEFAULT)
    10. UnsetSigChldHandler()
    11. env->CallStaticVoidMethod()【调用Zygote.callPostForkChildHooks】
  • system-server进程入口
  1. handleSystemServerProcess()
    1. closeServerSocket()
    2. Process.setArgV0()
    3. RuntimeInit.zygoteInit()
      1. redirectLogStreams()
      2. commonInit()【同上,见app_process的RuntimeInit】
      3. nativeZygoteInit()【调用到AndroidRuntime的onZygoteInit虚方法】
        1. AppRuntime::onZygoteInit()
          1. ProcessState::self()
          2. proc->startThreadPool()
      4. applicationInit()
        1. nativeSetExitWithoutCleanup()【顶层C库直接退出,调用_exit】
        2. VMRuntime.getRuntime().setTargetSdkVersion()【设置sdk版本】
        3. invokeStaticMain()
          1. throw new ZygoteInit.MethodAndArgsCaller(m, argv)【抛出异常退出调用栈,ZygoteInit.main()方法处理该异常】
  • 进入SystemServer的main方法

ZygoteInit.main()捕获异常MethodAndArgsCaller,调用其run方法。

  1. MethodAndArgsCaller.run()
    1. mMethod.invoke()【调用实际类的main方法】

启动新进程

  • ZygoteInit的套接字服务循环(runSelectLoop)
  1. while (true)
    1. selectReadable()
    2. acceptCommandPeer()
      1. if (index == 0)
        1. new ZygoteConnection
        2. peers.add()
      2. else
        1. peers.get(index).runOnce()【步骤二】
        2. peers.remove()
  • ZygoteConnection启动进程
  1. ZygoteConnection::runOnce()
    1. readArgumentList()
      1. mSocketReader.readLine()【第一行argc】
      2. for i = [0, argc)【每行一个参数】
        1. mSocketReader.readLine()
    2. mSocket.getAncillaryFileDescriptors()【通过UNIX套接字传递过来的文件描述符,用于标准输入等】
    3. if (parsedArgs.abiListQuery)
      1. handleAbiListQuery()【返回ZygoteInit的参数--abi-list=的值】
        1. mSocketOutStream.writeInt()
        2. mSocketOutStream.write()
    4. if (parsedArgs.runtimeInit && parsedArgs.invokeWith)
      1. Libcore.os.pipe()【创建管道,子进程的子进程返回进程id】
    5. Zygote.forkAndSpecialize()
      1. nativeForkAndSpecialize()
        1. ForkAndSpecializeCommon()【见流程“主流程”】
    6. if (pid == 0)【子进程】
      1. IoUtils.closeQuietly()【关闭ID返回管道的server端】
      2. handleChildProc()【子进程入口,步骤三】
    7. else【父进程】
      1. IoUtils.closeQuietly()【关闭ID返回管道的client端】
      2. handleParentProc()【父进程继续处理,步骤四】
  • 子进程入口(handleChildProc)
  1. closeSocket()
    1. mSocket.close()【关闭UNIX套接字连接】
  2. ZygoteInit.closeServerSocket()
    1. sServerSocket.close()【关闭UNIX侦听套接字】
  3. if (descriptors != null)
    1. ZygoteInit.reopenStdio()【native方法,复制描述符】
    2. foreach descriptors
      1. IoUtils.closeQuietly(fd)【关闭原描述符】
  4. if (parsedArgs.niceName)
    1. Process.setArgV0()【设置进程名】
  5. if (parsedArgs.runtimeInit)【参数--runtime-init】
    1. if (parsedArgs.invokeWith)
      1. WrapperInit.execApplication()【启动app_process】
        1. Zygote.execShell()【步骤五】
    2. else【这是APP应用正常启动方式】
      1. RuntimeInit.zygoteInit()【同上,见流程“主流程”】
  6. else
    1. 【提取第一个参数parsedArgs.remainingArgs[0]作为类名】
    2. if (parsedArgs.invokeWith)
      1. WrapperInit.execStandalone()【启动dalvikvm】
        1. Zygote.execShell()【步骤六】
    3. else
      1. ClassLoader.getSystemClassLoader()【外部可以指定classpath】
      2. ZygoteInit.invokeStaticMain()【同RuntimeInit.invokeStaticMain】
        1. 加载类
        2. throw new ZygoteInit.MethodAndArgsCaller(m, argv)【抛异常,退回调用栈,并调用指定类的main方法,见流程“主流程”】
  • 父进程继续处理(handleParentProc)
  1. if (pid > 0)【启动成功】
    1. setChildPgid()【子进程移动到请求进程的进程组中】
      1. ZygoteInit.setpgid()
  2. if (descriptors != null)
    1. foreach descriptors
      1. IoUtils.closeQuietly(fd)【关闭原描述符】
  3. if (pipeFd)
    1. 等待返回实际进程id
  4. mSocketOutStream.writeInt()【在套接字连接上返回实际进程id】
  5. 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>

  1. 【写入新进程id到pipeFd
  2. ZygoteInit.preload()【预加载类,资源,opengl】
  3. RuntimeInit.wrapperInit()
    1. applicationInit()【同上,见流程“主流程”】
  • WrapperInit的独立程序(execStandalone)

命令行格式为:

<invokeWith> /system/bin/dalvikvm -classpath <classPath> <className> <args>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值