| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
ykul8261
8年前发布

Android系统启动流程分析

   <p>随着Android版本的升级,aosp项目中的代码也有了些变化,本文基于Android 7.0分析Android系统启动流程.</p>    <p>简单来说Android系统启动大体如下:</p>    <p><img src="https://simg.open-open.com/show/bc8759c2d0ec10675c220ec765c34a24.png"></p>    <h2>init进程</h2>    <p>和所有Linux系统一样,Android系统的启动同样是从init进程启动.init进程会解析init.rc文件(关于init.rc中的语法,可以参见我之前写的 <a href="/misc/goto?guid=4959739031190179698" rel="nofollow,noindex">深入分析AIL语言及init.rc文件</a> ),加载相关目录,并启动相关服务</p>    <p>init进程在/system/core/init/init.c</p>    <p>init.rc文件在/system/core/rootdir下</p>    <p>在init.rc中,Zygote进程被启动.Zygote进程是Android所有进程的孵化器进程.init.rc通过include引入init.zygote.rc,这里以init.zygote64.rc为例,来看一下其中的代码:</p>    <pre>  <code class="language-java">service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server      class main      priority -20      user root      group root readproc      socket zygote stream 660 root system      onrestart write /sys/android_power/request_state wake      onrestart write /sys/power/state on      onrestart restart audioserver      onrestart restart cameraserver      onrestart restart media      onrestart restart netd      writepid /dev/cpuset/foreground/tasks</code></pre>    <p>我们队这个脚本简单分析:</p>    <p>1. service zygote /system/bin/app_process64 :service命令告诉init进程要创建一个名字为zygote的进程,这个zygote进程执行的程序是/system/bin/app_process64,后面是传给app_process64程序的参数.</p>    <p>3. socket zygote stream 660 root system :表示zygote进程需要一个名为”zygote”的socket,该socket用来实现进程间的通信.当新启动一个应用时,ActivityManagerService想向该Socket发起请求,请求zygote进程fork出一个新的进程.</p>    <p>4. 后面的onretart表示zygote重启时需要执行的动作.</p>    <h2>Zygote进程启动</h2>    <p>现在我们知道Zygote进程要执行的程序是/system/bin/app_process64,</p>    <p>它位于/frameworks/base/cmds/app_process/app_main.cpp当中,其入口函数是main():</p>    <pre>  <code class="language-java">int main(int argc, char* const argv[])  {      if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {          LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));      }        if (!LOG_NDEBUG) {        String8 argv_String;        for (int i = 0; i < argc; ++i) {          argv_String.append("\"");          argv_String.append(argv[i]);          argv_String.append("\" ");        }        ALOGV("app_process main with argv: %s", argv_String.string());      }        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));      // Process command line arguments      // ignore argv[0]      argc--;      argv++;      const char* spaced_commands[] = { "-cp", "-classpath" };        bool known_command = false;        int i;      for (i = 0; i < argc; i++) {          if (known_command == true) {            runtime.addOption(strdup(argv[i]));            ALOGV("app_process main add known option '%s'", argv[i]);            known_command = false;            continue;          }            for (int j = 0;               j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));               ++j) {            if (strcmp(argv[i], spaced_commands[j]) == 0) {              known_command = true;              ALOGV("app_process main found known command '%s'", argv[i]);            }          }            if (argv[i][0] != '-') {              break;          }          if (argv[i][1] == '-' && argv[i][2] == 0) {              ++i; // Skip --.              break;          }            runtime.addOption(strdup(argv[i]));          ALOGV("app_process main add option '%s'", argv[i]);      }        // Parse runtime arguments.  Stop at first unrecognized option.      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) {              //init.zygote64.rc中接受的参数,表示启动SystemServer组件              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;          }      }        Vector<String8> args;      if (!className.isEmpty()) {            args.add(application ? String8("application") : String8("tool"));          runtime.setClassNameAndArgs(className, argc - i, argv + i);            if (!LOG_NDEBUG) {            String8 restOfArgs;            char* const* argv_new = argv + i;            int argc_new = argc - i;            for (int k = 0; k < argc_new; ++k) {              restOfArgs.append("\"");              restOfArgs.append(argv_new[k]);              restOfArgs.append("\" ");            }            ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());          }      } else {          // We're in zygote mode.          maybeCreateDalvikCache();            if (startSystemServer) {              args.add(String8("start-system-server"));          }            char prop[PROP_VALUE_MAX];          if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {              LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",                  ABI_LIST_PROPERTY);              return 11;          }            String8 abiFlag("--abi-list=");          abiFlag.append(prop);          args.add(abiFlag);            // In zygote mode, pass all remaining arguments to the zygote          // main() method.          for (; i < argc; ++i) {              args.add(String8(argv[i]));          }      }        if (!niceName.isEmpty()) {          runtime.setArgv0(niceName.string(), true /* setProcName */);      }        if (zygote) {          //此处见到了我们熟悉的ZygoteInit,但该方法的具体实现在AndroidRuntime.start()          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.");      }  }</code></pre>    <p>该函数最主要的作用就是创建AppRuntime,该类同样是在该文件中定义,具体的定义如下:</p>    <pre>  <code class="language-java">class AppRuntime : public AndroidRuntime  {  public:      AppRuntime(char* argBlockStart, const size_t argBlockLength)          : AndroidRuntime(argBlockStart, argBlockLength)          , mClass(NULL)      {      }        void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {          mClassName = className;          for (int i = 0; i < argc; ++i) {               mArgs.add(String8(argv[i]));          }      }        virtual void onVmCreated(JNIEnv* env)      {          if (mClassName.isEmpty()) {              return; // Zygote. Nothing to do here.          }            char* slashClassName = toSlashClassName(mClassName.string());          mClass = env->FindClass(slashClassName);          if (mClass == NULL) {              ALOGE("ERROR: could not find class '%s'\n", mClassName.string());          }          free(slashClassName);            mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));      }        virtual void onStarted()      {          sp<ProcessState> proc = ProcessState::self();          ALOGV("App process: starting thread pool.\n");          proc->startThreadPool();            AndroidRuntime* ar = AndroidRuntime::getRuntime();          ar->callMain(mClassName, mClass, mArgs);            IPCThreadState::self()->stopProcess();      }        virtual void onZygoteInit()      {          sp<ProcessState> proc = ProcessState::self();          ALOGV("App process: starting thread pool.\n");          proc->startThreadPool();      }        virtual void onExit(int code)      {          if (mClassName.isEmpty()) {              // if zygote              IPCThreadState::self()->stopProcess();          }            AndroidRuntime::onExit(code);      }          String8 mClassName;      Vector<String8> mArgs;      jclass mClass;  };</code></pre>    <p>AppRuntime继承了AndroidRuntime,来继续看看AndroidRuntime.start()方法:</p>    <p>它在/frameworks/base/core/jni/AndroidRuntime.cpp,来看下源码:</p>    <pre>  <code class="language-java">/*   * Start the Android runtime.  This involves starting the virtual machine   * and calling the "static void main(String[] args)" method in the class   * named by "className".   *   * Passes the main function two arguments, the class name and the specified   * options string.   */  void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)  {      ALOGD(">>>>>> START %s uid %d <<<<<<\n",              className != NULL ? className : "(unknown)", getuid());        static const String8 startSystemServer("start-system-server");        /*       * 'startSystemServer == true' means runtime is obsolete and not run from       * init.rc anymore, so we print out the boot start event here.       */      for (size_t i = 0; i < options.size(); ++i) {          if (options[i] == startSystemServer) {             /* track our progress through the boot sequence */             const int LOG_BOOT_PROGRESS_START = 3000;             LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));          }      }        const char* rootDir = getenv("ANDROID_ROOT");      if (rootDir == NULL) {          rootDir = "/system";          if (!hasDir("/system")) {              LOG_FATAL("No root directory specified, and /android does not exist.");              return;          }          setenv("ANDROID_ROOT", rootDir, 1);      }        //const char* kernelHack = getenv("LD_ASSUME_KERNEL");      //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);          //1. 启动虚拟机      if (startVm(&mJavaVM, &env, zygote) != 0) {          return;      }      onVmCreated(env);        //2. 调用startReg()注册JNI方法      if (startReg(env) < 0) {          ALOGE("Unable to register all android natives\n");          return;      }        /*       * We want to call main() with a String array with arguments in it.       * At present we have two arguments, the class name and an option string.       * Create an array to hold them.       */          jclass stringClass;      jobjectArray strArray;      jstring classNameStr;        stringClass = env->FindClass("java/lang/String");      assert(stringClass != NULL);      strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);      assert(strArray != NULL);      classNameStr = env->NewStringUTF(className);      assert(classNameStr != NULL);      env->SetObjectArrayElement(strArray, 0, classNameStr);        for (size_t i = 0; i < options.size(); ++i) {          jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());          assert(optionsStr != NULL);          env->SetObjectArrayElement(strArray, i + 1, optionsStr);      }        /*       * 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);      if (startClass == NULL) {          ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);          /* keep going */      } else {           //3. 本质就是调用com.android.intrnal.os.ZygoteInit类的main函数          jmethodID startMeth = env->GetStaticMethodID(startClass, "main",              "([Ljava/lang/String;)V");          if (startMeth == NULL) {              ALOGE("JavaVM unable to find main() in '%s'\n", className);              /* keep going */          } else {              env->CallStaticVoidMethod(startClass, startMeth, strArray);    #if 0              if (env->ExceptionCheck())                  threadExitUncaughtException(env);  #endif          }      }      free(slashClassName);        ALOGD("Shutting down VM\n");      if (mJavaVM->DetachCurrentThread() != JNI_OK)          ALOGW("Warning: unable to detach main thread\n");      if (mJavaVM->DestroyJavaVM() != 0)          ALOGW("Warning: VM did not shut down cleanly\n");  }</code></pre>    <p>在start()中主要做三件事情:</p>    <p>1. 调用startVM函数启动虚拟机</p>    <p>2. 调用startReg注册JNI方法</p>    <p>3. 调用com.android.internal.os.ZygoteInit.java类的main函数.</p>    <p>这里我们重点来ZygoteInit.java.它在</p>    <p>rameworks/base/core/Java/com/android/internal/os/ZygoteInit.java,我们直接来看他的main方法:</p>    <pre>  <code class="language-java">public static void main(String argv[]) {          ZygoteServer zygoteServer = new ZygoteServer();            // Mark zygote start. This ensures that thread creation will throw          // an error.          ZygoteHooks.startZygoteNoThreadCreation();            // Zygote goes into its own process group.          try {              Os.setpgid(0, 0);          } catch (ErrnoException ex) {              throw new RuntimeException("Failed to setpgid(0,0)", ex);          }            try {              Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");              RuntimeInit.enableDdms();              // Start profiling the zygote initialization.              SamplingProfilerIntegration.start();                boolean startSystemServer = false;              String socketName = "zygote";              String abiList = null;              for (int i = 1; i < argv.length; i++) {                  if ("start-system-server".equals(argv[i])) {                      startSystemServer = true;                  } else if (argv[i].startsWith(ABI_LIST_ARG)) {                      abiList = argv[i].substring(ABI_LIST_ARG.length());                  } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {                      socketName = argv[i].substring(SOCKET_NAME_ARG.length());                  } else {                      throw new RuntimeException("Unknown command line argument: " + argv[i]);                  }              }                if (abiList == null) {                  throw new RuntimeException("No ABI list supplied.");              }              //创建名为zygote的socket              zygoteServer.registerServerSocket(socketName);              Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");              EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,                  SystemClock.uptimeMillis());              preload();              EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                  SystemClock.uptimeMillis());              Trace.traceEnd(Trace.TRACE_TAG_DALVIK);                // Finish profiling the zygote initialization.              SamplingProfilerIntegration.writeZygoteSnapshot();                // Do an initial gc to clean up after startup              Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");              gcAndFinalize();              Trace.traceEnd(Trace.TRACE_TAG_DALVIK);                // Disable tracing so that forked processes do not inherit stale tracing tags from              // Zygote.              Trace.setTracingEnabled(false);                // Zygote process unmounts root storage spaces.              Zygote.nativeUnmountStorageOnInit();                ZygoteHooks.stopZygoteNoThreadCreation();                if (startSystemServer) {                  //启动SystemServer组件                  startSystemServer(abiList, socketName, zygoteServer);              }                Log.i(TAG, "Accepting command socket connections");              //等待ActivityManagerService请求              zygoteServer.runSelectLoop(abiList);                zygoteServer.closeServerSocket();          } catch (Zygote.MethodAndArgsCaller caller) {              caller.run();          } catch (Throwable ex) {              Log.e(TAG, "System zygote died with exception", ex);              zygoteServer.closeServerSocket();              throw ex;          }      }</code></pre>    <p>这里的main()方法中主要做了三件事情</p>    <p>1. 通过registerServerSocket来创建Socket,用来和ActivityManagerService通信</p>    <p>2. 通过startSystemServer方法来启动SystemServer</p>    <p>3. 通过runSelectLoop方法来等待来自ActivityManagerService请求</p>    <h2>Socket创建</h2>    <p>下面我们分别来看看对应着几个方法的具体实现:</p>    <p>首先来看ZygoteServer.resiterServerSocket(),它在</p>    <p>/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java当中:</p>    <pre>  <code class="language-java">void registerServerSocket(String socketName) {          if (mServerSocket == null) {              int fileDesc;              final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;              try {                  String env = System.getenv(fullSocketName);                  //从环境变量env中获取文件描述符                  fileDesc = Integer.parseInt(env);              } catch (RuntimeException ex) {                  throw new RuntimeException(fullSocketName + " unset or invalid", ex);              }                try {                  //通过文件描述符创建socket,该描述符代表/dev/socket/zygote文件.                  FileDescriptor fd = new FileDescriptor();                  fd.setInt$(fileDesc);                  mServerSocket = new LocalServerSocket(fd);              } catch (IOException ex) {                  throw new RuntimeException(                          "Error binding to local socket '" + fileDesc + "'", ex);              }          }      }</code></pre>    <h2>SystemServer启动</h2>    <p>再回到ZygoteInit中看startSystemServer()方法:</p>    <pre>  <code class="language-java">/**       * Prepare the arguments and fork for the system server process.       */      private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)              throws Zygote.MethodAndArgsCaller, RuntimeException {          long capabilities = posixCapabilitiesAsBits(              OsConstants.CAP_IPC_LOCK,              OsConstants.CAP_KILL,              OsConstants.CAP_NET_ADMIN,              OsConstants.CAP_NET_BIND_SERVICE,              OsConstants.CAP_NET_BROADCAST,              OsConstants.CAP_NET_RAW,              OsConstants.CAP_SYS_MODULE,              OsConstants.CAP_SYS_NICE,              OsConstants.CAP_SYS_RESOURCE,              OsConstants.CAP_SYS_TIME,              OsConstants.CAP_SYS_TTY_CONFIG,              OsConstants.CAP_WAKE_ALARM          );          /* Containers run without this capability, so avoid setting it in that case */          if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {              capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);          }          /* 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,1032,3001,3002,3003,3006,3007,3009,3010",              "--capabilities=" + capabilities + "," + capabilities,              "--nice-name=system_server",              "--runtime-args",              "com.android.server.SystemServer",          };          ZygoteConnection.Arguments parsedArgs = null;            int pid;            try {              parsedArgs = new ZygoteConnection.Arguments(args);              ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);              ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);                //通过forSystemServer()方法创建第一个子进程,此处即SystemServer进程              pid = Zygote.forkSystemServer(                      parsedArgs.uid, parsedArgs.gid,                      parsedArgs.gids,                      parsedArgs.debugFlags,                      null,                      parsedArgs.permittedCapabilities,                      parsedArgs.effectiveCapabilities);          } catch (IllegalArgumentException ex) {              throw new RuntimeException(ex);          }            //pid=0表示子进程,此处就是SystemServer进程          if (pid == 0) {              if (hasSecondZygote(abiList)) {                  waitForSecondaryZygote(socketName);              }              //Zygote创建的子进程(此处就是SystemServer)不需要使用Zygote中创建的Socket文件描述符,因此通过closeServerSocket()关闭它.              zygoteServer.closeServerSocket();              handleSystemServerProcess(parsedArgs);          }            return true;      }</code></pre>    <p>接着我们看一下handleSystemServerProcess()方法:</p>    <pre>  <code class="language-java">/**       * Finish remaining work for the newly forked system server process.       */        private static void handleSystemServerProcess(              ZygoteConnection.Arguments parsedArgs)              throws Zygote.MethodAndArgsCaller {            // set umask to 0077 so new files and directories will default to owner-only permissions.          Os.umask(S_IRWXG | S_IRWXO);            if (parsedArgs.niceName != null) {              Process.setArgV0(parsedArgs.niceName);          }            final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");          if (systemServerClasspath != null) {              performSystemServerDexOpt(systemServerClasspath);          }            if (parsedArgs.invokeWith != null) {              String[] args = parsedArgs.remainingArgs;              // If we have a non-null system server class path, we'll have to duplicate the              // existing arguments and append the classpath to it. ART will handle the classpath              // correctly when we exec a new process.              if (systemServerClasspath != null) {                  String[] amendedArgs = new String[args.length + 2];                  amendedArgs[0] = "-cp";                  amendedArgs[1] = systemServerClasspath;                  System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);              }                WrapperInit.execApplication(parsedArgs.invokeWith,                      parsedArgs.niceName, parsedArgs.targetSdkVersion,                      VMRuntime.getCurrentInstructionSet(), null, args);          } else {              ClassLoader cl = null;              if (systemServerClasspath != null) {                  cl = createSystemServerClassLoader(systemServerClasspath,                                                     parsedArgs.targetSdkVersion);                    Thread.currentThread().setContextClassLoader(cl);              }                 //调用zygoteInit()方法进一步执行启动SystemServer组件的操作              RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);          }        }</code></pre>    <p>继续来看 RuntimeInit.zygoteInit()函数的具体代码,它在</p>    <p>/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:</p>    <pre>  <code class="language-java">public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)              throws Zygote.MethodAndArgsCaller {          if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");          redirectLogStreams();            commonInit();          //native方法,用来执行一个Binder进程间同步新机制的初始化工作.之后,这个进程中的Binder对象就可以方便的进行进程间通信了          nativeZygoteInit();          //执行com.android.server.SystemServer类的main函数          applicationInit(targetSdkVersion, argv, classLoader);      }       private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)              throws Zygote.MethodAndArgsCaller {              //...省略众多代码          invokeStaticMain(args.startClass, args.startArgs, classLoader);      }    //真正反射执行SystemServer的main方法   private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)              throws Zygote.MethodAndArgsCaller {          Class<?> cl;            try {              cl = Class.forName(className, true, classLoader);          } catch (ClassNotFoundException ex) {              throw new RuntimeException(                      "Missing class when invoking static main " + className,                      ex);          }            Method m;          try {          // 通过反射执行SystemServer的main()方法              m = cl.getMethod("main", new Class[] { String[].class });          } catch (NoSuchMethodException ex) {              //...          } catch (SecurityException ex) {              //...          }          //...      }</code></pre>    <p>接上文来看一下SystemServer.main(),</p>    <p>它在/frameworks/base/services/java/com/android/server/SystemServer.java</p>    <pre>  <code class="language-java">public class SystemServer{      public static void main(String[] args) {          new SystemServer().run();      }          private void run() {          try {              //...省略一些初始化操作                android.os.Process.setThreadPriority(                  android.os.Process.THREAD_PRIORITY_FOREGROUND);              android.os.Process.setCanSelfBackground(false);              //初始化主线程Looper              Looper.prepareMainLooper();                //创建SystemServiceManager对象              mSystemServiceManager = new SystemServiceManager(mSystemContext);              LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);          } finally {              Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);          }                // 启动关键服务              startBootstrapServices();              //启动核心服务              startCoreServices();              //启动其他服务              startOtherServices();              //...省略多行代码                //启动消息循环              Looper.loop();        }    }</code></pre>    <h2>Socket监听</h2>    <p>到现在关于ZygoteInit.main()放中两个主要的方法</p>    <p>ZygoteServer.registerServerSocket() 和 startSystemServer()</p>    <p>我们已经分析完了,他们分别完成Socket的创建以及SystemServer的启动工作,接下来回到 ZygoteServer.runSelectLoop() 方法:</p>    <pre>  <code class="language-java">oid runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {          ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();          ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();            fds.add(mServerSocket.getFileDescriptor());          peers.add(null);            while (true) {              StructPollfd[] pollFds = new StructPollfd[fds.size()];              for (int i = 0; i < pollFds.length; ++i) {                  pollFds[i] = new StructPollfd();                  pollFds[i].fd = fds.get(i);                  pollFds[i].events = (short) POLLIN;              }              try {                  Os.poll(pollFds, -1);              } catch (ErrnoException ex) {                  throw new RuntimeException("poll failed", ex);              }              for (int i = pollFds.length - 1; i >= 0; --i) {                  if ((pollFds[i].revents & POLLIN) == 0) {                      continue;                  }                  if (i == 0) {                     //监听Socket链接,如果你做过Socket编程就发现此处充当了服务端Socket                      ZygoteConnection newPeer = acceptCommandPeer(abiList);                      peers.add(newPeer);                      fds.add(newPeer.getFileDesciptor());                  } else {                      //重点关注runOnce()方法                      boolean done = peers.get(i).runOnce(this);                      if (done) {                          peers.remove(i);                          fds.remove(i);                      }                  }              }          }      }</code></pre>    <p>该方法非常简单就是不断的从已经创建的Socket中取出ZygoteConnection请求,继续来:ZygoteConnection.runOnce():</p>    <pre>  <code class="language-java">boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {            String args[];          Arguments parsedArgs = null;          FileDescriptor[] descriptors;            //...省略一堆参数解析和判断逻辑              try {              //...省略多行              fd = zygoteServer.getServerSocketFileDescriptor();                if (fd != null) {                  fdsToClose[1] = fd.getInt$();              }                fd = null;              //关键:通过forkAndSpecialize()方法创建非Zygote进程,即普通应用              pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,                      parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,                      parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,                      parsedArgs.appDataDir);          } catch (ErrnoException ex) {              //...          } catch (IllegalArgumentException ex) {              //...          } catch (ZygoteSecurityException ex) {             //...          }            try {              if (pid == 0) {//此处就是普通应用的进程                  // in child                  //此处创建的进程同样用不到Zygote进程中创建的Sockt,所以关闭它                  zygoteServer.closeServerSocket();                  IoUtils.closeQuietly(serverPipeFd);                  serverPipeFd = null;                  //该方法最终调用程序的入口main方法                  handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);                  return true;              } else {                  // in parent...pid of < 0 means failure                  IoUtils.closeQuietly(childPipeFd);                  childPipeFd = null;                  return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);              }          } finally {              IoUtils.closeQuietly(childPipeFd);              IoUtils.closeQuietly(serverPipeFd);          }      }</code></pre>    <p>在runOnce()方法中,Zygote进程根据ActivityManagerService的请求,通过forkAndSpecialize()方法来为应用创建新进程,并执行应用的入口main()方法.</p>    <p>到现在我们可以用一张顺序图大体的表示上述的整个流程:</p>    <p><img src="https://simg.open-open.com/show/4d41793e54aa474f5803dfce19ca7709.png"></p>    <p>总体而言整个流程还是非常清晰的.另外关于Zygote进程及其他进程的关系,可以看如下图:</p>    <h2>总结</h2>    <p>系统启动时init进程会创建Zygote进程,Zygote进程负责后续Android应用框架层的其他进程的创建和启动.Zygote进程会首先创建一个SystemSever进程,然后由SystemServer负责启动系统关键服务,如ActivityManagerService或者PackageManagerService等.当需要启动一个新的应用时,ActivityManagerService会通过Socket进行通信,Zygote的Socket收到请求之后会为这个应用fork一个新进程,fork成功之后,执行的工作就交给虚拟机.</p>    <p> </p>    <p>来自:http://blog.csdn.net/dd864140130/article/details/57624948</p>    <p> </p>    
 本文由用户 ykul8261 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!
 本文地址:https://www.open-open.com/lib/view/open1488166888620.html
Socket 安卓开发 Android开发 移动开发