转载

android系统启动Zygote—2

Zygote一共干了那些事情

  • 创建AppRuntime对象,并调用它的start。此后的活动则由AppRuntime来控制。
  • 调用startVm创建Java虚拟机,然后调用startReg来注册JNI函数。
  • 通过JNI调用com.android.internal.os.ZygoteInit类的main函数,从此进入了Java世界。然而在这个世界刚开创的时候,什么东西都没有。
  • 调用registerZygoteSocket。通过这个函数,它可以响应子孙后代的请求。同时Zygote调用preloadClasses和preloadResources,为Java世界添砖加瓦。
  • Zygote觉得自己工作压力太大,便通过调用startSystemServer分裂一个子进程system_server来为Java世界服务。
  • Zygote完成了Java世界的初创工作,它已经很满足了。下一步该做的就是调用runSelectLoopMode后,便沉沉地睡去了

前一篇讲了前面3步,现在来解析后面3步

调用registerZygoteSocket

调用registerZygoteSocket。通过这个函数,它可以响应子孙后代的请求。同时Zygote调用preloadClasses和preloadResources,为Java世界添砖加瓦。

ZygoteServer.java

private static void registerZygoteSocket() {
    if(sServerSocket == null) {
        intfileDesc;
        try{
           //从环境变量中获取Socket的fd,还记得zygote是如何启动的吗?
//这个环境变量由execv传入。
          String env = System.getenv(ANDROID_SOCKET_ENV);
          fileDesc = Integer.parseInt(env);
       }
       try{
         //创建服务端Socket,这个Socket将listen并accept Client
         sServerSocket= new LocalServerSocket(createFileDescriptor(fileDesc));
       }
       }
}

谁是客户端?

怎么处理客户端的消息?

preloadClasses

预加载classes,由于classes很多,非常多,

preloadClasses看起来是如此简单,但是你知道它有多少个类需要预先加载吗?

在framework中搜索名为“preloaded-classes”的文件,最后会在framework/base目录下找到

android8.0看到的是4900多个,所以android启动有多慢?

preloadResources

干的事情和preloadClasses类似的,把资源进行预加载。

在UI编程中常使用的com.android.R.XXX资源,是系统默认的资源,它们就是由Zygote加载的

启动system_server

ZygoteInit.java

private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.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,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* 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) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            handleSystemServerProcess(parsedArgs);
        }

    }

一开始就是配置sysgemserver启动的参数

然后从zygote里面fork出systemserver进程

pid=0就是子进程,所以handleSystemServerProcess就是system_server进程的工作。

runSelectLoopMode

刚才说了调用registerZygoteSocket注册了服务端的zygote socket,

这里就是处理客户端请求的地方。

ZygoteServer.java

/**
     * Runs the zygote process s select loop. Accepts new connections as
     * they happen, and reads commands from connections one spawn-request s
     * worth at a time.
     *
     * @throws Zygote.MethodAndArgsCaller in a child process when a main()
     * should be executed.
     */
     for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    boolean done = peers.get(i).runOnce(this);
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
  • 处理客户连接和客户请求。其中客户在Zygote中用ZygoteConnection对象来表示。
  • 客户的请求由ZygoteConnection的runOnce来处理
原文  http://www.demanmath.com/index.php/2020/06/23/androidxitongqidongzygote-2/
正文到此结束
Loading...