Zygote进程

init进程解析init.rc,fock出Zygote进程,执行Zygote的main,初始化appruntime,执行appruntime start,启动虚拟机,注册Android方法,反射调用com.android.internal.os.ZygoteInit#main()方法

Zygote进程mian方法主要执行逻辑:

  • 初始化DDMS;

  • 注册Zygote进程的socket通讯;

  • 预加载Zygote中的各种类,资源文件,OpenGL,类库,Text资源等等;

  • 初始化完成之后fork出SystemServer进程;

  • fork出SystemServer进程之后,关闭socket连接;

  • SystemServer进程是android中一个很重要的进程由Zygote进程启动;

  • SystemServer进程主要用于启动系统中的服务;

  • SystemServer进程启动服务的启动函数为main函数;

  • SystemServer在执行过程中首先会初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等之后才开始启动系统服务;

  • SystemServer进程将系统服务分为三类:boot服务,core服务和other服务,并逐步启动

  • SystemServer进程在尝试启动服务之前会首先尝试与Zygote建立socket通讯,只有通讯成功之后才会开始尝试启动服务;

  • 创建的系统服务过程中主要通过SystemServiceManager对象来管理,通过调用服务对象的构造方法和onStart方法初始化服务的相关变量;

  • 服务对象都有自己的异步消息对象,并运行在单独的线程中;

系统启动时kernel/init/main.c文件中的kernel_init()函数会做一些硬件相关的基础工作,比如 CPU 初始化和内存初始化等,然后会执行platform/system/core目录下的init程序,该程序即 Android 的init进程对应的程序。该程序的对应代码是platform/system/core/init.cpp,打开该文件并找到它的入口函数:

// 注意这两行引入
#include "property_service.h"
#include "service.h"

int main(int argc, char** argv) {
  ... // 一些必要的环境变量配置和启动其他Linux进程

  // 执行在头部引入的property_service.h的start_property_service()函数,启动systemService
  start_property_service();

  // 解析配置文件
  Parser& parser = Parser::GetInstance();
  // 解析service
  parser.AddSectionParser("service",std::make_unique<ServiceParser>());
  parser.AddSectionParser("on", std::make_unique<ActionParser>());
  parser.AddSectionParser("import", std::make_unique<ImportParser>());

  parser.ParseConfig("/init.rc");
  ...

  ActionManager& am = ActionManager::GetInstance();

  ... // 配置am命令参数

  while (true) {
    // 使用epoll机制 + 死循环,使init进程一直运行,类似Looper#loop()

    // 默认一直阻塞,直到有事情需要做被唤醒
    int epoll_timeout_ms = -1;

    if (...) {
      am.ExecuteOneCommand();
      // 一些赋值逻辑,可能是0
      epoll_timeout_ms = ...;
    }

    // 调用epoll_wait使init进程沉睡或者...
    epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms);
  }

  return 0;
}

init进程解析init.zygote.rc后,会 forkzygote进程,然后在zygote进程中执行/system/bin/app_process程序,执行该程序的目的是初始化zygote进程。

接下来我们打开platform/frameworks/base/cmds/app_process/app_main.cpp文件,来分析初始化zygote进程时做了哪些事情,目光定位在main()函数上:

int main(int argc, char* const argv[])
{
    // 创建 AppRuntime的成员变量
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

    ...

    // 解析运行时参数,赋值zygote和startSystemServer
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }

    if (!className.isEmpty()) {
        ...
    } else {
        ...
        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }
    }

    if (zygote) {
        // 调用 ZygoteInit#main()
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

  发现AppRuntime类继承于AndroidRuntime,而AppRuntime类中是没有start()函数的,因此回到上方的main()函数中,实际上当执行AppRuntime#start()时实际上是执行了AndroidRuntime#start(),下面我们来看看AndroidRuntime类,它位于platform/frameworks/base/core/jni/AndroidRuntime.cpp:

void AndroidRuntime::start(const char* className, ..., bool zygote)
{
    static const String8 startSystemServer("start-system-server");

    ...

    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;

    startVm(&mJavaVM, &env, zygote);
    onVmCreated(env);

    /*
     * Register android functions.
     */
    startReg(env);

    /*
     * We want to call main() with a String array with arguments in it.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    stringClass = env->FindClass("java/lang/String");
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
        "([Ljava/lang/String;)V");
    env->CallStaticVoidMethod(startClass, startMeth, strArray);

    ...
}

根据AndroidRuntime名称和上述代码可以分析得出,该函数启动了 Android 系统运行时库,其中它主要做了三件事:

调用startVmVM()函数启动虚拟机
调用startReg()函数注册 Android 的 Java 方法,其实在这里就是 JNI 方法
反射调用 Java 类com.android.internal.os.ZygoteInit#main()方法,并把 fork zygote进程时的参数传入用来辅助初始化zygote进程

 com.android.internal.os.ZygoteInit

public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();

    // 标记Zygote开始初始化,并Hook确保不创建其他线程
    ZygoteHooks.startZygoteNoThreadCreation();

    // Zygote进入自己的进程组
    try {
        Os.setpgid(0, 0);
    } catch (ErrnoException ex) {
        throw new RuntimeException("Failed to setpgid(0,0)", ex);
    }

    ...

    boolean startSystemServer = false;
    String socketName = "zygote";

    // 解析参数,初始化局部变量
    for (int i = 1; i < argv.length; i++) {
        if ("start-system-server".equals(argv[i])) {
            startSystemServer = true;
        }
        ...
    }

    // 注册一个名为zygote的ServerSocket,
    zygoteServer.registerServerSocket(socketName);

    // 第一次启动时会预加载资源
    if (!enableLazyPreload) {
        ...
        preload(bootTimingsTraceLog);
    }
    ...

    // 停止Hook不创建其他线程,也就是说允许创建其他线程
    ZygoteHooks.stopZygoteNoThreadCreation();

    // 这里一定是true,启动SystemServer
    if (startSystemServer) {
        startSystemServer(abiList, socketName, zygoteServer);
    }

    // 运行zygote进程的select循环
    zygoteServer.runSelectLoop(abiList);

    zygoteServer.closeServerSocket();
}

ZygoteServer#registerServerSocket()创建 Java 层的 ServerSocket 对象

上面说到ZygoteServer#registerServerSocket()创建了一个名为zygote的 Socket 资源,我们知道,Socket 是 IPC 通信的一种方式,该 Socket 资源在后期被用在和 AMS 等服务进行进程间通信。下面我们来看ZygoteServer#registerServerSocket()的具体实现,ZygoteServer.java位于com.android.internal.os.ZygoteServer.java:

class ZygoteServer {

  private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";

  private LocalServerSocket mServerSocket;

  ZygoteServer() {
  }

  void registerServerSocket(String socketName) {
      if (mServerSocket == null) {
          int fileDesc;

          // fullSocketname的值是ANDROID_SOCKET_zygote
          final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;

          // 获取Socket名称对应的环境变量
          String env = System.getenv(fullSocketName);
          fileDesc = Integer.parseInt(env);

          // 根据环境变量创建文件描述符
          FileDescriptor fd = new FileDescriptor();
          fd.setInt$(fileDesc);

          // 根据文件描述符创建Socket
          mServerSocket = new LocalServerSocket(fd);
    }
  }
}

在上述com.android.internal.os.ZygoteServer.java中也能看到 Socket 资源的前缀常量,因此它在这里就获取到了名为ANDROID_SOCKET_zygote的文件描述符,并在 Java 层创建了LocalServerSocket的服务端 Socket 对象。

ZygoteInit.java 启动 system_server 进程的过程

/**
  * Prepare the arguments and fork for the system server process.
  */
private static boolean startSystemServer(String socketName,
    ZygoteServer zygoteServer) {

  /* Hardcoded command line to start the system server */
  String args[] = {
    ...
    "--nice-name=system_server", // 指定进程名字 system_server
    "--runtime-args",
    "com.android.server.SystemServer", // 指定进程fork后要执行的程序
  };

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

  // 从zygote进程fork system_server进程
  int pid = Zygote.forkSystemServer(
      parsedArgs.uid, parsedArgs.gid,
      parsedArgs.gids,
      parsedArgs.debugFlags,
      null,
      parsedArgs.permittedCapabilities,
      parsedArgs.effectiveCapabilities);

  return true;
}

这段代码中指定了 fork 新进程的名称为system_server,当进程被 fork 后会调用com.android.server.SystemServer#main()方法。

先简单的看一下 fork 新进程的方法:

    /**
     * Fork system_server进程,并返回该进程的pid
     */
    public static int forkSystemServer(int uid, int gid, ...) {
        VM_HOOKS.preFork();

        //
        int pid = nativeForkSystemServer(uid, gid, ...);

        VM_HOOKS.postForkCommon();
        return pid;
    }

    native private static int nativeForkSystemServer(int uid, int gid, ...);

上述代码也比较清晰明了,实际上是调用了native方法 fork 了一个新的进程。

SystemServer.java 初始化 system_server 进程的过程

接着会执行com.android.server.SystemServer#main()方法,我们看一下该方法:

public final class SystemServer {
  /**
    * The main entry point from zygote.
    */
  public static void main(String[] args) {
    new SystemServer().run();
  }

  public SystemServer() {
    mFactoryTestMode = FactoryTest.getMode();
    mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
  }

  private void run() {
    ...

    // Mmmmmm... more memory!
    VMRuntime.getRuntime().clearGrowthLimit();

    // The system server has to run all of the time, so it needs to be
    // as efficient as possible with its memory usage.
    VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

    // Some devices rely on runtime fingerprint generation, so make sure
    // we've defined it before booting further.
    Build.ensureFingerprintProperty();

    // Within the system server, it is an error to access Environment paths without
    // explicitly specifying a user.
    Environment.setUserRequired(true);

    // Within the system server, any incoming Bundles should be defused
    // to avoid throwing BadParcelableException.
    BaseBundle.setShouldDefuse(true);

    // Ensure binder calls into the system always run at foreground priority.
    BinderInternal.disableBackgroundScheduling(true);

    // Increase the number of binder threads in system_server
    BinderInternal.setMaxThreads(sMaxBinderThreads);

    // Prepare the main looper thread (this thread).
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
    android.os.Process.setCanSelfBackground(false);
    // 准备MainLooper
    Looper.prepareMainLooper();

    // 初始化家在系统的native服务组件
    System.loadLibrary("android_servers");

    // Check whether we failed to shut down last time we tried.
    // This call may not return.
    performPendingShutdown();

    // 初始化系统Context
    createSystemContext();

    // 创建系统服务管理器,这个很关键
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

    // Prepare the thread pool for init tasks that can be parallelized
    SystemServerInitThreadPool.get();

    // 启动一些系统核心服务,很关键
    startBootstrapServices();
    startCoreServices();
    startOtherServices();

    SystemServerInitThreadPool.shutdown();

    ...

    // 让MainLooper无限循环的运行下去
    Looper.loop();
    hrow new RuntimeException("Main thread loop unexpectedly exited");
  }
}

看到这一段代码时我们可能会有一种在黑暗中走了很久,终于看到阳光的感觉,我们看到main()方法中实例化了SystemServer,并调用该对象的run()方法,然后开始初始化system_server进程,该方法主要做了以下几件事:

一些有关系统的初始化工作,例如 VM 虚拟机、运行时环境和线程池优先级等
调用Looper#prepareMainLooper()准备 Android 主线程Looper
调用System#loadLibrary()初始化native环境
调用createSystemContext()创建应用上下文
实例化SystemServiceManager以备后续启动系统中的其他核心服务
调用start<Name>Services()启动相关核心服务
调用Looper#loop()让主线程的Looper跑起来

/**
 * Starts the small tangle of critical services that are needed to get
 * the system off the ground.  These services have complex mutual dependencies
 * which is why we initialize them all in one place here.  Unless your service
 * is also entwined in these dependencies, it should be initialized in one of
 * the other functions.
 */
private void startBootstrapServices() {
  ...
  Installer installer = mSystemServiceManager.startService(Installer.class);

  mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);

  // 启动AMS,Acitivity管理服务
  mActivityManagerService = mSystemServiceManager.startService(
      ActivityManagerService.Lifecycle.class).getService();
  mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
  mActivityManagerService.setInstaller(installer);

  // 启动电源管理服务
  mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
  mActivityManagerService.initPowerManagement();

  mSystemServiceManager.startService(LightsService.class);

  // 启动显示管理服务
  mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
  mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

  ...

  // 启动包管理服务
  mPackageManagerService = PackageManagerService.main(mSystemContext,
    installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
  mFirstBoot = mPackageManagerService.isFirstBoot();
  mPackageManager = mSystemContext.getPackageManager();

  // 启动用户管理服务
  mSystemServiceManager.startService(UserManagerService.LifeCycle.class);

  // 初始化缓存包中资源属性
  AttributeCache.init(mSystemContext);

  // 为系统进程设置Application实例
  mActivityManagerService.setSystemProcess();

  ...
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值