zygote和system server启动过程解析
openkk
13年前
<div class="BlogContent TextContent"> <p><span style="font-family:Liberation Serif, serif;">Zygote</span>的启动过程解析。</p> <p><span style="font-family:Liberation Serif, serif;">Zygote</span>实际上是一个用户态应用程序,由启动脚本负责启动。在启动脚本中<span style="font-family:Liberation Serif, serif;">Zygote</span>叫做<span style="font-family:Liberation Serif, serif;">app_process</span>。下面分析<span style="font-family:Liberation Serif, serif;">app_main.cpp</span>中的启动<span style="font-family:Liberation Serif, serif;">Zygote</span>的过程。</p> <p><span style="font-family:Liberation Serif, serif;">main</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>设置<span style="font-family:Liberation Serif, serif;">runtime</span>的<span style="font-family:Liberation Serif, serif;">mParentDir</span>为<span style="font-family:Liberation Serif, serif;">/usr/bin</span>,<span style="font-family:Liberation Serif, serif;">mArgC</span>为<span style="font-family:Liberation Serif, serif;">zygote</span>参数个数,<span style="font-family:Liberation Serif, serif;">mArgV</span>为<span style="font-family:Liberation Serif, serif;">zygote</span>参数(<span style="font-family:Liberation Serif, serif;">-Xzygote /system/bin --zygote --start-system-server</span>)</p> <p><span style="font-family:Liberation Serif, serif;"> |__runtime.start</span>(<span style="font-family:Liberation Serif, serif;">AndroidRuntime::start</span>)</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>设置环境变量<span style="font-family:Liberation Serif, serif;">ANDROID_ROOT</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__startVm()</span>:启动<span style="font-family:Liberation Serif, serif;">VM</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>设置启动虚拟机参数,如:<span style="font-family:Liberation Serif, serif;">checkjni,</span>进程堆大小<span style="font-family:Liberation Serif, serif;">16MB</span>等</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">JNI_CreateJavaVM()</span>启动虚拟机,之后<span style="font-family:Liberation Serif, serif;">JavaVM</span>和虚拟机主线程的<span style="font-family:Liberation Serif, serif;">JNIEnv</span>变量有效</p> <p><span style="font-family:Liberation Serif, serif;"> |__startReg()</span>:向虚拟机主线程注册<span style="font-family:Liberation Serif, serif;">JNI</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span><span style="font-family:Liberation Serif, serif;">com.android.internal.os.ZygoteInit.main(从JNI调用,</span>从此进入<span style="font-family:Liberation Serif, serif;">JAVA</span>世界)</p> <p><span style="font-family:Liberation Serif, serif;"> |__registerZygoteSocket()</span>:创建<span style="font-family:Liberation Serif, serif;">Zygote</span>服务端本地<span style="font-family:Liberation Serif, serif;">socket</span>,用于监听客户端的连接请求</p> <p><span style="font-family:Liberation Serif, serif;"> |__preloadClasses()</span>:预先加载<span style="font-family:Liberation Serif, serif;">preloaded-classes</span>文件中指定的类(此过程耗时较大,好处是加快后续应用程序的启动)</p> <p><span style="font-family:Liberation Serif, serif;"> |__preloadResources()</span>:预先加载资源</p> <p><span style="font-family:Liberation Serif, serif;"> |__gc()</span>:手动执行一次垃圾回收</p> <p><span style="font-family:Liberation Serif, serif;"> |__startSystemServer()</span>:启动一个子进程来运行<span style="font-family:Liberation Serif, serif;">system_server</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>硬编码启动<span style="font-family:Liberation Serif, serif;">system_server</span>时使用的参数</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">Zygote.forkSystemServer()</span>创建子进程</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">forkAndSpecializeCommon()</span>创建子进程(调用<span style="font-family:Liberation Serif, serif;">fork()</span>创建子进程且设置子进程相关<span style="font-family:Liberation Serif, serif;">uid</span>、<span style="font-family:Liberation Serif, serif;">gid</span>等属性)</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>对于创建子进程失败则直接将<span style="font-family:Liberation Serif, serif;">Zygote</span>进程杀死(<span style="font-family:Liberation Serif, serif;">Zygote</span>进程与<span style="font-family:Liberation Serif, serif;">system_server</span>进程生死与共)</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>返回子进程<span style="font-family:Liberation Serif, serif;">ID</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>在子进程中调用<span style="font-family:Liberation Serif, serif;">handleSystemServerProcess()</span>运行<span style="font-family:Liberation Serif, serif;">system_server</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>关闭父进程<span style="font-family:Liberation Serif, serif;">Zygote</span>打开的本地服务端<span style="font-family:Liberation Serif, serif;">socket</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>执行<span style="font-family:Liberation Serif, serif;">RuntimeInit.zygoteInit()</span>运行<span style="font-family:Liberation Serif, serif;">system_server</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">AppRuntime::onZygoteInit()</span>。实际上是与<span style="font-family:Liberation Serif, serif;">binder</span>建立联系</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">invokeStaticMain()</span>执行<span style="font-family:Liberation Serif, serif;">systemserver</span>类的<span style="font-family:Liberation Serif, serif;">main</span>函数</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">Class.forName()</span>根据类名反射出类对象</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用类的<span style="font-family:Liberation Serif, serif;">getMethod()</span>方法获取<span style="font-family:Liberation Serif, serif;">systemserver</span>类的<span style="font-family:Liberation Serif, serif;">main</span>方法</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">ZygoteInit.MethodAndArgsCaller()</span>抛出一个异常且该异常中包含<span style="font-family:Liberation Serif, serif;">systemserver</span>类的<span style="font-family:Liberation Serif, serif;">main</span>方法</p> <p><span style="font-family:Liberation Serif, serif;"> |__runSelectLoopMode()</span>:使用多路复用<span style="font-family:Liberation Serif, serif;">I/O</span>机制监听连接到<span style="font-family:Liberation Serif, serif;">Zygote</span>本地服务器的<span style="font-family:Liberation Serif, serif;">socket</span>且执行响应处理</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>进入死循环监听<span style="font-family:Liberation Serif, serif;">Zygote</span>本地服务端<span style="font-family:Liberation Serif, serif;">socket</span>,当有客户端连接<span style="font-family:Liberation Serif, serif;">Zygote</span>本地服务端<span style="font-family:Liberation Serif, serif;">socket</span>后,调用<span style="font-family:Liberation Serif, serif;">ZygoteConnection.runOnce()</span>执行该服务请求</p> <p><span style="font-family:Liberation Serif, serif;"> |__ZygoteConnection.runOnce()</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">Zygote.forkAndSpecialize()</span>函数创建一个子进程</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>在子进程中执行<span style="font-family:Liberation Serif, serif;">handleChildProc()</span>处理客户端请求</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>关闭父进程<span style="font-family:Liberation Serif, serif;">Zygote</span>创建的服务端<span style="font-family:Liberation Serif, serif;">socket</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>执行<span style="font-family:Liberation Serif, serif;">RuntimeInit.zygoteInit()</span>运行客户端请求</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">AppRuntime::onZygoteInit()</span>。实际上是与<span style="font-family:Liberation Serif, serif;">binder</span>建立联系</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">invokeStaticMain()</span>执行客户端请求类的<span style="font-family:Liberation Serif, serif;">main</span>函数</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">Class.forName()</span>根据类名反射出类对象</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用类的<span style="font-family:Liberation Serif, serif;">getMethod()</span>方法获取客户端请求类的<span style="font-family:Liberation Serif, serif;">main</span>方法</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用<span style="font-family:Liberation Serif, serif;">ZygoteInit.MethodAndArgsCaller()</span>抛出一个异常且该异常中包含客户端请求类的<span style="font-family:Liberation Serif, serif;">main</span>方法</p> <p><span style="font-family:Liberation Serif, serif;"> |__MethodAndArgsCaller.run()</span>:在异常处理函数处,用于启动连接到<span style="font-family:Liberation Serif, serif;">Zygote</span>服务器端<span style="font-family:Liberation Serif, serif;">socket</span>的客户端程序以及<span style="font-family:Liberation Serif, serif;">system_server</span>主函数。(<span style="font-family:Liberation Serif, serif;">Zygote</span>处理连接端数据时在最后使用抛异常的机制运行客户端主函数)。</p> <p>可以得出一个结论:<span style="font-family:Liberation Serif, serif;">system_server</span>的启动过程和其他应用进程的启动过程是一致的,他们都是<span style="font-family:Liberation Serif, serif;">Zygote</span>的子进程。</p> <p><span style="font-family:Liberation Serif, serif;">SystemServer</span>启动解析</p> <p><span style="font-family:Liberation Serif, serif;">main</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__System.loadLibrary(“android_servers”)</span>加载<span style="font-family:Liberation Serif, serif;">JNI</span>库</p> <p><span style="font-family:Liberation Serif, serif;"> |__init1()</span>执行<span style="font-family:Liberation Serif, serif;">init1</span>(<span style="font-family:Liberation Serif, serif;">JNI</span>函数)</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>执行<span style="font-family:Liberation Serif, serif;">system_init()</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>设置参数准备将system_server加入<span style="font-family:Liberation Serif, serif;">binder</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>调用执行<span style="font-family:Liberation Serif, serif;">Java</span>代码的<span style="font-family:Liberation Serif, serif;">init2</span>函数</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>创建一个线程执行<span style="font-family:Liberation Serif, serif;">android.server.ServerThread</span></p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>启动各种服务,如:电源管理、电池管理、蓝牙等</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>等待新的服务请求。</p> <p><span style="font-family:Liberation Serif, serif;"> |__</span>最终将<span style="font-family:Liberation Serif, serif;">system_server</span>添加到<span style="font-family:Liberation Serif, serif;">binder</span>中</p> <p>当有新的服务请求到后,<span style="font-family:Liberation Serif, serif;">system_server</span>会调用服务请求的处理函数做如下事情:</p> <p><span style="font-family:Liberation Serif, serif;">1</span>)与<span style="font-family:Liberation Serif, serif;">Zygote</span>本地服务端<span style="font-family:Liberation Serif, serif;">Socket</span>建立连接;</p> <p><span style="font-family:Liberation Serif, serif;">2</span>)将待执行的类名组成指定的格式发送给<span style="font-family:Liberation Serif, serif;">Zygote</span>;</p> <p><span style="font-family:Liberation Serif, serif;">3</span>)<span style="font-family:Liberation Serif, serif;">Zygote</span>接收到客户端的请求后,调用<span style="font-family:Liberation Serif, serif;">ZygoteConnection.runOnce()</span>执行该服务请求,即:创建一个子进程来运行指定类对象的<span style="font-family:Liberation Serif, serif;">main</span>函数。</p> </div>