前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >笔记:Zygote和SystemServer进程启动过程

笔记:Zygote和SystemServer进程启动过程

作者头像
用户1172465
发布2018-01-08 14:30:20
7620
发布2018-01-08 14:30:20
举报
文章被收录于专栏:everhadeverhad

简述

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

Zygote的启动

它以服务的形式被启动。

创建虚拟机

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

代码语言:javascript
复制
/* start the virtual machine. */
startVM(&mJavaVM, &env);
/* Register android functions. */
startReg(env);

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

ZygoteInit.main

代码语言:javascript
复制
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进程

代码语言:javascript
复制
/**
 * 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进程

代码语言:javascript
复制
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()

代码语言:javascript
复制
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

代码语言:javascript
复制
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():

代码语言:javascript
复制
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

代码语言:javascript
复制
public static final void init2() {
    Thread thr = new ServerThread();
    thr.setName("android.server.ServerThread");
    thr.start();
}

ServerThread继承自Thread。

ServerThread.run

代码语言:javascript
复制
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和其它服务使用者进程进行就行交互。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-01-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述
  • Zygote的启动
    • 创建虚拟机
      • ZygoteInit.main
        • 创建Socket
          • 创建System进程
            • 轮询等待AMS请求创建App进程
            • System进程的启动
              • ZygoteInit.handleSystemServerProcess()
                • RuntimeInit.zygoteInit
                  • SystemServer.main
                    • SystemServer.init2
                      • ServerThread.run
                      相关产品与服务
                      数据库
                      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档