zoukankan      html  css  js  c++  java
  • 笔记:Zygote和SystemServer进程启动过程

    简述

    Android设备启动过程中,先是Linux内核加载完,接着Android中的第一个进程init启动,它会启动一些需要开机启动的进程。
    Zygote就是进程init启动起来的。Android中所有应用程序进程,以及运行系统关键服务的System进程都是由Zygote创建的。它通过复制自身的形式创建其它进程。Zygote在启动时会在内部创建一个虚拟机实例,因此,通过复制Zygote得到的其它应用程序进程和System进程都可以快速地在内部获得一个虚拟机地拷贝。Zygote启动完成后就立即将System进程启动,以便各种关键服务被启动运行。

    Zygote的启动

    它以服务的形式被启动。

    创建虚拟机

    进程内创建一个虚拟机实例,并注册一系列JNI方法。
    frameworks/base/core/jni/AndroidRuntime.cpp

    /* start the virtual machine. */
    startVM(&mJavaVM, &env);
    /* Register android functions. */
    startReg(env);
    

    接下来执行“com.android.internal.os.ZygoteInit”Java类的main方法继续执行启动。

    ZygoteInit.main

    package com.android.internal.os;
    import android.net.LocalServerSocket;
    ...
    public class ZygoteInit {
      private static LocalServerSocket sServerSocket;
    
      public static void main(String argv[]) {
        ...
        registerZygoteSocket();
        ...
        if (argv[1].equals("true")) {
            startSystemServer();
        } else if (!argv[1].equals("false")) {
            throw new RuntimeException(argv[0] + USAGE_STRING);
        }
        ...
        if (ZYGOTE_FORK_MODE) {
            runForkMode();
        } else {
            runSelectLoopMode();
        }
        ...
        closeServerSocket();
        ...
      }
    }
    

    创建Socket

    Zygote调用registerZygoteSocket();创建一个LocalServerSocket sServerSocket的Server端Socket,等待以后运行在System进程中的服务ActivityManagerService创建的Client端Socket连接,然后通过Socket进程间通信通知Zygote创建新的应用程序进程。

    创建System进程

    /**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
        /* Hardcoded command line to start the system server */
        String args[] = new String[] {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
                "--capabilities=130104352,130104352",
                "--rlimit=8,",
                "--runtime-init",
                "--nice-name=system_server",
                "com.android.server.SystemServer",
            };
            ...
        ZygoteConnection.Arguments parsedArgs = null;
        int pid;
    
        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
    
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, rlimits,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
    
        /* For child process */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }
    
        return true;
    }
    

    变量args保存启动System进程的参数。
    Zygote.forkSystemServer()复制当前进程来创建子进程。
    handleSystemServerProcess()继续处理System进程的启动。

    轮询等待AMS请求创建App进程

    private static void runSelectLoopMode() throws MethodAndArgsCaller {
      ArrayList<FileDescriptor> fds = new ArrayList();
      ArrayList<ZygoteConnection> peers = new ArrayList();
      FileDescriptor[] fdArray = new FileDescriptor[4];
    
      fds.add(sServerSocket.getFileDescriptor());
      peers.add(null);
    
      while (true) {
        ...
          try {
              fdArray = fds.toArray(fdArray);
              index = selectReadable(fdArray);
          } catch (IOException ex) {
              throw new RuntimeException("Error in select()", ex);
          }
    
          if (index < 0) {
              throw new RuntimeException("Error in select()");
          } else if (index == 0) {
              ZygoteConnection newPeer = acceptCommandPeer();
              peers.add(newPeer);
              fds.add(newPeer.getFileDesciptor());
          } else {
              boolean done;
              done = peers.get(index).runOnce();
    
              if (done) {
                  peers.remove(index);
                  fds.remove(index);
              }
          }
      }
    }
    
    /**
     * Waits for and accepts a single command connection. Throws
     * RuntimeException on failure.
     */
    private static ZygoteConnection acceptCommandPeer() {
        try {
            return new ZygoteConnection(sServerSocket.accept());
        } catch (IOException ex) {
            throw new RuntimeException(
                    "IOException during accept()", ex);
        }
    }
    

    无限循环,等待来自AMS创建的Socket连接。
    sServerSocket在fds[0]位置。
    每当accept()返回一个连接后,将对应此连接的newPeer.getFileDesciptor()套接字描述添加到fds(第0位置后),下一次读取到数据时,若在fds[0]以后的,说明是前面的newPeer连接收到的AMS的创建新应用程序进程的请求。
    runOnce()用来处理AMS创建新应用程序进程的请求。

    System进程的启动

    ZygoteInit.handleSystemServerProcess()执行System进程的启动操作。

    ZygoteInit.handleSystemServerProcess()

    private static void handleSystemServerProcess(
          ZygoteConnection.Arguments parsedArgs)
          throws ZygoteInit.MethodAndArgsCaller {
    
      closeServerSocket();
    
      /*
       * Pass the remaining arguments to SystemServer.
       * "--nice-name=system_server com.android.server.SystemServer"
       */
      RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
      /* should never reach here */
    }
    

    Zygote复制自身创建的子进程做为System进程,这样它得到了Zygote的Server Socket,但是用不到,所以第一句closeServerSocket()关闭此套接字。

    RuntimeInit.zygoteInit

    package com.android.internal.os;
    
    public class RuntimeInit {
      public static final void zygoteInit(String[] argv)
              throws ZygoteInit.MethodAndArgsCaller {
          ...
          commonInit();
          zygoteInitNative();
          ...
          // Remaining arguments are passed to the start class's static main
          String startClass = argv[curArg++];
          String[] startArgs = new String[argv.length - curArg];
    
          System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
          invokeStaticMain(startClass, startArgs);
      }  
    }
    

    zygoteInitNative()在System进程中启动一个Binder线程池。
    RuntimeInit.invokeStaticMain()静态方法调用"com.android.server.SystemServer"的main方法。

    SystemServer.main

    传递调用native方法init1():

    class SystemServer {
      /**
         * This method is called from Zygote to initialize the system. This will cause the native
         * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
         * up into init2() to start the Android services.
         */
        native public static void init1(String[] args);
    }
    

    init1()的工作:
    注册Service Manager的死亡通知:调用binderDied()。System进程执行kill结束自己。

    创建SurfaceFlinger、和SensorService两个服务。

    返回SystemServer.init2()继续启动java语言开发的系统服务。

    SystemServer.init2

    public static final void init2() {
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }
    

    ServerThread继承自Thread。

    ServerThread.run

    class ServerThread extends Thread {
      @Override
      public void run() {
          Looper.prepare();
          ...
          // Critical services...
          try {
              ...
              Slog.i(TAG, "Activity Manager");
              context = ActivityManagerService.main(factoryTest);
              ...
              Slog.i(TAG, "Package Manager");
              pm = PackageManagerService.main(context,
                      factoryTest != SystemServer.FACTORY_TEST_OFF);
              ...
              Slog.i(TAG, "Content Manager");
              ContentService.main(context,
                      factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
              ...
              Slog.i(TAG, "Window Manager");
              wm = WindowManagerService.main(context, power,
                      factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
              ServiceManager.addService(Context.WINDOW_SERVICE, wm);
              ...
              ((ActivityManagerService)ServiceManager.getService("activity"))
                      .setWindowManager(wm);
              ...
          } catch (RuntimeException e) {
              Slog.e("System", "Failure starting core service", e);
          }
          ...
          Looper.loop();
          Slog.d(TAG, "System ServerThread is exiting!");
      }
    }
    

    启动各个Service然后注册到ServiceManager。
    各个服务都使用Binder和其它服务使用者进程进行就行交互。

    (本文使用Atom编写)

  • 相关阅读:
    Supervisor 管理进程,Cloud Insight 监控进程,完美!
    【灵魂拷问】你为什么要来学习Node.js呢?
    Web数据交互技术
    请求与上传文件,Session简介,Restful API,Nodemon
    Express服务器开发
    HTTP协议,到底是什么鬼?
    大学我都是自学走来的,这些私藏的实用工具/学习网站我贡献出来了,建议收藏精品推荐
    Node.js安装使用-VueCLI安装使用-工程化的Vue.js开发
    React开发环境准备
    【可视化】Vue基础
  • 原文地址:https://www.cnblogs.com/everhad/p/6290855.html
Copyright © 2011-2022 走看看