经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android 世界中,谁喊醒了 Zygote ?
来源:cnblogs  作者:秉心说  时间:2019/10/16 11:43:15  对本文有异议

本文基于 Android 9.0 , 代码仓库地址 : android_9.0.0_r45

文中源码链接:

SystemServer.java

ActivityManagerService.java

Process.java

ZygoteProcess.java

ZygoteSystemServer 启动流程还不熟悉的建议阅读下面两篇文章:

Java 世界的盘古和女娲 —— Zygote

Zygote 家的大儿子 —— SystemServer

Zygote 作为 Android 世界的受精卵,在成功繁殖出 system_server 进程之后并没有完全功成身退,仍然承担着受精卵的责任。Zygote 通过调用其持有的 ZygoteServer 对象的 runSelectLoop() 方法开始等待客户端的呼唤,有求必应。客户端的请求无非是创建应用进程,以 startActivity() 为例,假如开启的是一个尚未创建进程的应用,那么就会向 Zygote 请求创建进程。下面将从 客户端发送请求服务端处理请求 两方面来进行解析。

客户端发送请求

startActivity() 的具体流程这里就不分析了,系列后续文章会写到。我们直接看到创建进程的 startProcess() 方法,该方法在 ActivityManagerService 中,后面简称 AMS

Process.startProcess()

  1. > ActivityManagerService.java
  2. private ProcessStartResult startProcess(String hostingType, String entryPoint,
  3. ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
  4. String seInfo, String requiredAbi, String instructionSet, String invokeWith,
  5. long startTime) {
  6. try {
  7. checkTime(startTime, "startProcess: asking zygote to start proc");
  8. final ProcessStartResult startResult;
  9. if (hostingType.equals("webview_service")) {
  10. startResult = startWebView(entryPoint,
  11. app.processName, uid, uid, gids, runtimeFlags, mountExternal,
  12. app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
  13. app.info.dataDir, null,
  14. new String[] {PROC_START_SEQ_IDENT + app.startSeq});
  15. } else {
  16. // 新建进程
  17. startResult = Process.start(entryPoint,
  18. app.processName, uid, uid, gids, runtimeFlags, mountExternal,
  19. app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
  20. app.info.dataDir, invokeWith,
  21. new String[] {PROC_START_SEQ_IDENT + app.startSeq});
  22. }
  23. checkTime(startTime, "startProcess: returned from zygote!");
  24. return startResult;
  25. } finally {
  26. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  27. }
  28. }

调用 Process.start() 方法新建进程,继续追进去:

  1. > Process.java
  2. public static final ProcessStartResult start(
  3. // android.app.ActivityThread,创建进程后会调用其 main() 方法
  4. final String processClass,
  5. final String niceName, // 进程名
  6. int uid, int gid, int[] gids,
  7. int runtimeFlags, int mountExternal,
  8. int targetSdkVersion,
  9. String seInfo,
  10. String abi,
  11. String instructionSet,
  12. String appDataDir,
  13. String invokeWith, // 一般新建应用进程时,此参数不为 null
  14. String[] zygoteArgs) {
  15. return zygoteProcess.start(processClass, niceName, uid, gid, gids,
  16. runtimeFlags, mountExternal, targetSdkVersion, seInfo,
  17. abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
  18. }

继续调用 zygoteProcess.start()

  1. > ZygoteProess.java
  2. public final Process.ProcessStartResult start(final String processClass,
  3. final String niceName,
  4. int uid, int gid, int[] gids,
  5. int runtimeFlags, int mountExternal,
  6. int targetSdkVersion,
  7. String seInfo,
  8. String abi,
  9. String instructionSet,
  10. String appDataDir,
  11. String invokeWith,
  12. String[] zygoteArgs) {
  13. try {
  14. return startViaZygote(processClass, niceName, uid, gid, gids,
  15. runtimeFlags, mountExternal, targetSdkVersion, seInfo,
  16. abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
  17. zygoteArgs);
  18. } catch (ZygoteStartFailedEx ex) {
  19. Log.e(LOG_TAG,
  20. "Starting VM process through Zygote failed");
  21. throw new RuntimeException(
  22. "Starting VM process through Zygote failed", ex);
  23. }
  24. }

调用 startViaZygote() 方法。终于看到 Zygote 的身影了。

startViaZygote()

  1. > ZygoteProcess.java
  2. private Process.ProcessStartResult startViaZygote(final String processClass,
  3. final String niceName,
  4. final int uid, final int gid,
  5. final int[] gids,
  6. int runtimeFlags, int mountExternal,
  7. int targetSdkVersion,
  8. String seInfo,
  9. String abi,
  10. String instructionSet,
  11. String appDataDir,
  12. String invokeWith,
  13. boolean startChildZygote, // 是否克隆 zygote 进程的所有状态
  14. String[] extraArgs)
  15. throws ZygoteStartFailedEx {
  16. ArrayList<String> argsForZygote = new ArrayList<String>();
  17. // --runtime-args, --setuid=, --setgid=,
  18. // and --setgroups= must go first
  19. // 处理参数
  20. argsForZygote.add("--runtime-args");
  21. argsForZygote.add("--setuid=" + uid);
  22. argsForZygote.add("--setgid=" + gid);
  23. argsForZygote.add("--runtime-flags=" + runtimeFlags);
  24. if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
  25. argsForZygote.add("--mount-external-default");
  26. } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
  27. argsForZygote.add("--mount-external-read");
  28. } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
  29. argsForZygote.add("--mount-external-write");
  30. }
  31. argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
  32. // --setgroups is a comma-separated list
  33. if (gids != null && gids.length > 0) {
  34. StringBuilder sb = new StringBuilder();
  35. sb.append("--setgroups=");
  36. int sz = gids.length;
  37. for (int i = 0; i < sz; i++) {
  38. if (i != 0) {
  39. sb.append(',');
  40. }
  41. sb.append(gids[i]);
  42. }
  43. argsForZygote.add(sb.toString());
  44. }
  45. if (niceName != null) {
  46. argsForZygote.add("--nice-name=" + niceName);
  47. }
  48. if (seInfo != null) {
  49. argsForZygote.add("--seinfo=" + seInfo);
  50. }
  51. if (instructionSet != null) {
  52. argsForZygote.add("--instruction-set=" + instructionSet);
  53. }
  54. if (appDataDir != null) {
  55. argsForZygote.add("--app-data-dir=" + appDataDir);
  56. }
  57. if (invokeWith != null) {
  58. argsForZygote.add("--invoke-with");
  59. argsForZygote.add(invokeWith);
  60. }
  61. if (startChildZygote) {
  62. argsForZygote.add("--start-child-zygote");
  63. }
  64. argsForZygote.add(processClass);
  65. if (extraArgs != null) {
  66. for (String arg : extraArgs) {
  67. argsForZygote.add(arg);
  68. }
  69. }
  70. synchronized(mLock) {
  71. // 和 Zygote 进程进行 socket 通信
  72. return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
  73. }
  74. }

前面一大串代码都是在处理参数,大致浏览即可。核心在于最后的 openZygoteSocketIfNeeded()zygoteSendArgsAndGetResult() 这两个方法。从方法命名就可以看出来,这里要和 Zygote 进行 socket 通信了。还记得 ZygoteInit.main() 方法中调用的 registerServerSocketFromEnv() 方法吗?它在 Zygote 进程中创建了服务端 socket。

openZygoteSocketIfNeeded()

先来看看 openZygoteSocketIfNeeded() 方法。

  1. > ZygoteProcess.java
  2. private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
  3. Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
  4. // 未连接或者连接已关闭
  5. if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
  6. try {
  7. // 开启 socket 连接
  8. primaryZygoteState = ZygoteState.connect(mSocket);
  9. } catch (IOException ioe) {
  10. throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
  11. }
  12. maybeSetApiBlacklistExemptions(primaryZygoteState, false);
  13. maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
  14. }
  15. if (primaryZygoteState.matches(abi)) {
  16. return primaryZygoteState;
  17. }
  18. // 当主 zygote 没有匹配成功,尝试 connect 第二个 zygote
  19. if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
  20. try {
  21. secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
  22. } catch (IOException ioe) {
  23. throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
  24. }
  25. maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
  26. maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
  27. }
  28. if (secondaryZygoteState.matches(abi)) {
  29. return secondaryZygoteState;
  30. }
  31. throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
  32. }

如果与 Zygote 进程的 socket 连接未开启,则尝试开启,可能会产生阻塞和重试。连接调用的是 ZygoteState.connect() 方法,ZygoteStateZygoteProcess 的内部类。

  1. > ZygoteProcess.java
  2. public static class ZygoteState {
  3. final LocalSocket socket;
  4. final DataInputStream inputStream;
  5. final BufferedWriter writer;
  6. final List<String> abiList;
  7. boolean mClosed;
  8. private ZygoteState(LocalSocket socket, DataInputStream inputStream,
  9. BufferedWriter writer, List<String> abiList) {
  10. this.socket = socket;
  11. this.inputStream = inputStream;
  12. this.writer = writer;
  13. this.abiList = abiList;
  14. }
  15. public static ZygoteState connect(LocalSocketAddress address) throws IOException {
  16. DataInputStream zygoteInputStream = null;
  17. BufferedWriter zygoteWriter = null;
  18. final LocalSocket zygoteSocket = new LocalSocket();
  19. try {
  20. zygoteSocket.connect(address);
  21. zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());
  22. zygoteWriter = new BufferedWriter(new OutputStreamWriter(
  23. zygoteSocket.getOutputStream()), 256);
  24. } catch (IOException ex) {
  25. try {
  26. zygoteSocket.close();
  27. } catch (IOException ignore) {
  28. }
  29. throw ex;
  30. }
  31. String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
  32. Log.i("Zygote", "Process: zygote socket " + address.getNamespace() + "/"
  33. + address.getName() + " opened, supported ABIS: " + abiListString);
  34. return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
  35. Arrays.asList(abiListString.split(",")));
  36. }
  37. ...
  38. }

通过 socket 连接 Zygote 远程服务端。

再回头看之前的 zygoteSendArgsAndGetResult() 方法。

zygoteSendArgsAndGetResult()

  1. > ZygoteProcess.java
  2. private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
  3. ZygoteState zygoteState, ArrayList<String> args)
  4. throws ZygoteStartFailedEx {
  5. try {
  6. ...
  7. final BufferedWriter writer = zygoteState.writer;
  8. final DataInputStream inputStream = zygoteState.inputStream;
  9. writer.write(Integer.toString(args.size()));
  10. writer.newLine();
  11. // 向 zygote 进程发送参数
  12. for (int i = 0; i < sz; i++) {
  13. String arg = args.get(i);
  14. writer.write(arg);
  15. writer.newLine();
  16. }
  17. writer.flush();
  18. // 是不是应该有一个超时时间?
  19. Process.ProcessStartResult result = new Process.ProcessStartResult();
  20. // Always read the entire result from the input stream to avoid leaving
  21. // bytes in the stream for future process starts to accidentally stumble
  22. // upon.
  23. // 读取 zygote 进程返回的子进程 pid
  24. result.pid = inputStream.readInt();
  25. result.usingWrapper = inputStream.readBoolean();
  26. if (result.pid < 0) { // pid 小于 0 ,fork 失败
  27. throw new ZygoteStartFailedEx("fork() failed");
  28. }
  29. return result;
  30. } catch (IOException ex) {
  31. zygoteState.close();
  32. throw new ZygoteStartFailedEx(ex);
  33. }
  34. }

通过 socket 发送请求参数,然后等待 Zygote 进程返回子进程 pid 。客户端的工作到这里就暂时完成了,我们再追踪到服务端,看看服务端是如何处理客户端请求的。

Zygote 处理客户端请求

Zygote 处理客户端请求的代码在 ZygoteServer.runSelectLoop() 方法中。

  1. > ZygoteServer.java
  2. Runnable runSelectLoop(String abiList) {
  3. ...
  4. while (true) {
  5. ...
  6. try {
  7. // 有事件来时往下执行,没有时就阻塞
  8. Os.poll(pollFds, -1);
  9. } catch (ErrnoException ex) {
  10. throw new RuntimeException("poll failed", ex);
  11. }
  12. for (int i = pollFds.length - 1; i >= 0; --i) {
  13. if ((pollFds[i].revents & POLLIN) == 0) {
  14. continue;
  15. }
  16. if (i == 0) { // 有新客户端连接
  17. ZygoteConnection newPeer = acceptCommandPeer(abiList);
  18. peers.add(newPeer);
  19. fds.add(newPeer.getFileDesciptor());
  20. } else { // 处理客户端请求
  21. try {
  22. ZygoteConnection connection = peers.get(i);
  23. // fork 子进程,并返回包含子进程 main() 函数的 Runnable 对象
  24. final Runnable command = connection.processOneCommand(this);
  25. if (mIsForkChild) {
  26. // 位于子进程
  27. if (command == null) {
  28. throw new IllegalStateException("command == null");
  29. }
  30. return command;
  31. } else {
  32. // 位于父进程
  33. if (command != null) {
  34. throw new IllegalStateException("command != null");
  35. }
  36. if (connection.isClosedByPeer()) {
  37. connection.closeSocket();
  38. peers.remove(i);
  39. fds.remove(i);
  40. }
  41. }
  42. } catch (Exception e) {
  43. ...
  44. } finally {
  45. mIsForkChild = false;
  46. }
  47. }
  48. }
  49. }
  50. }

acceptCommandPeer() 方法用来响应新客户端的 socket 连接请求。processOneCommand() 方法用来处理客户端的一般请求。

processOneCommand()

  1. > ZygoteConnection.java
  2. Runnable processOneCommand(ZygoteServer zygoteServer) {
  3. String args[];
  4. Arguments parsedArgs = null;
  5. FileDescriptor[] descriptors;
  6. try {
  7. // 1. 读取 socket 客户端发送过来的参数列表
  8. args = readArgumentList();
  9. descriptors = mSocket.getAncillaryFileDescriptors();
  10. } catch (IOException ex) {
  11. throw new IllegalStateException("IOException on command socket", ex);
  12. }
  13. ...
  14. // 2. fork 子进程
  15. pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
  16. parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
  17. parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
  18. parsedArgs.instructionSet, parsedArgs.appDataDir);
  19. try {
  20. if (pid == 0) {
  21. // 处于进子进程
  22. zygoteServer.setForkChild();
  23. // 关闭服务端 socket
  24. zygoteServer.closeServerSocket();
  25. IoUtils.closeQuietly(serverPipeFd);
  26. serverPipeFd = null;
  27. // 3. 处理子进程事务
  28. return handleChildProc(parsedArgs, descriptors, childPipeFd,
  29. parsedArgs.startChildZygote);
  30. } else {
  31. // 处于 Zygote 进程
  32. IoUtils.closeQuietly(childPipeFd);
  33. childPipeFd = null;
  34. // 4. 处理父进程事务
  35. handleParentProc(pid, descriptors, serverPipeFd);
  36. return null;
  37. }
  38. } finally {
  39. IoUtils.closeQuietly(childPipeFd);
  40. IoUtils.closeQuietly(serverPipeFd);
  41. }
  42. }

processOneCommand() 方法大致可以分为五步,下面逐步分析。

readArgumentList()

  1. > ZygoteConnection.java
  2. private String[] readArgumentList()
  3. throws IOException {
  4. int argc;
  5. try {
  6. // 逐行读取参数
  7. String s = mSocketReader.readLine();
  8. if (s == null) {
  9. // EOF reached.
  10. return null;
  11. }
  12. argc = Integer.parseInt(s);
  13. } catch (NumberFormatException ex) {
  14. throw new IOException("invalid wire format");
  15. }
  16. // See bug 1092107: large argc can be used for a DOS attack
  17. if (argc > MAX_ZYGOTE_ARGC) {
  18. throw new IOException("max arg count exceeded");
  19. }
  20. String[] result = new String[argc];
  21. for (int i = 0; i < argc; i++) {
  22. result[i] = mSocketReader.readLine();
  23. if (result[i] == null) {
  24. // We got an unexpected EOF.
  25. throw new IOException("truncated request");
  26. }
  27. }
  28. return result;
  29. }

读取客户端发送过来的请求参数。

forkAndSpecialize()

  1. > Zygote.java
  2. public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
  3. int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
  4. int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir) {
  5. VM_HOOKS.preFork();
  6. // Resets nice priority for zygote process.
  7. resetNicePriority();
  8. int pid = nativeForkAndSpecialize(
  9. uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
  10. fdsToIgnore, startChildZygote, instructionSet, appDataDir);
  11. // Enable tracing as soon as possible for the child process.
  12. if (pid == 0) {
  13. Trace.setTracingEnabled(true, runtimeFlags);
  14. // Note that this event ends at the end of handleChildProc,
  15. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
  16. }
  17. VM_HOOKS.postForkCommon();
  18. return pid;
  19. }

nativeForkAndSpecialize() 是一个 native 方法,在底层 fork 了一个新进程,并返回其 pid。不要忘记了这里的 一次fork,两次返回pid > 0 说明还是父进程。pid = 0 说明进入了子进程。子进程中会调用 handleChildProc,而父进程中会调用 handleParentProc()

handleChildProc()

  1. > ZygoteConnection.java
  2. private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
  3. FileDescriptor pipeFd, boolean isZygote) {
  4. closeSocket(); // 关闭 socket 连接
  5. ...
  6. if (parsedArgs.niceName != null) {
  7. // 设置进程名
  8. Process.setArgV0(parsedArgs.niceName);
  9. }
  10. if (parsedArgs.invokeWith != null) {
  11. WrapperInit.execApplication(parsedArgs.invokeWith,
  12. parsedArgs.niceName, parsedArgs.targetSdkVersion,
  13. VMRuntime.getCurrentInstructionSet(),
  14. pipeFd, parsedArgs.remainingArgs);
  15. // Should not get here.
  16. throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
  17. } else {
  18. if (!isZygote) { // 新建应用进程时 isZygote 参数为 false
  19. return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
  20. null /* classLoader */);
  21. } else {
  22. return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
  23. parsedArgs.remainingArgs, null /* classLoader */);
  24. }
  25. }
  26. }

当看到 ZygoteInit.zygoteInit() 时你应该感觉很熟悉了,接下来的流程就是:

ZygoteInit.zygoteInit() -> RuntimeInit.applicationInit() -> findStaticMain()

SystemServer 进程的创建流程一致。这里要找的 main 方法就是 ActivityThrad.main()ActivityThread 虽然并不是一个线程,但你可以把它理解为应用的主线程。

handleParentProc()

  1. > ZygoteConnection.java
  2. private void handleParentProc(int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd) {
  3. if (pid > 0) {
  4. setChildPgid(pid);
  5. }
  6. if (descriptors != null) {
  7. for (FileDescriptor fd: descriptors) {
  8. IoUtils.closeQuietly(fd);
  9. }
  10. }
  11. boolean usingWrapper = false;
  12. if (pipeFd != null && pid > 0) {
  13. int innerPid = -1;
  14. try {
  15. // Do a busy loop here. We can't guarantee that a failure (and thus an exception
  16. // bail) happens in a timely manner.
  17. final int BYTES_REQUIRED = 4; // Bytes in an int.
  18. StructPollfd fds[] = new StructPollfd[] {
  19. new StructPollfd()
  20. };
  21. byte data[] = new byte[BYTES_REQUIRED];
  22. int remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS;
  23. int dataIndex = 0;
  24. long startTime = System.nanoTime();
  25. while (dataIndex < data.length && remainingSleepTime > 0) {
  26. fds[0].fd = pipeFd;
  27. fds[0].events = (short) POLLIN;
  28. fds[0].revents = 0;
  29. fds[0].userData = null;
  30. int res = android.system.Os.poll(fds, remainingSleepTime);
  31. long endTime = System.nanoTime();
  32. int elapsedTimeMs = (int)((endTime - startTime) / 1000000l);
  33. remainingSleepTime = WRAPPED_PID_TIMEOUT_MILLIS - elapsedTimeMs;
  34. if (res > 0) {
  35. if ((fds[0].revents & POLLIN) != 0) {
  36. // Only read one byte, so as not to block.
  37. int readBytes = android.system.Os.read(pipeFd, data, dataIndex, 1);
  38. if (readBytes < 0) {
  39. throw new RuntimeException("Some error");
  40. }
  41. dataIndex += readBytes;
  42. } else {
  43. // Error case. revents should contain one of the error bits.
  44. break;
  45. }
  46. } else if (res == 0) {
  47. Log.w(TAG, "Timed out waiting for child.");
  48. }
  49. }
  50. if (dataIndex == data.length) {
  51. DataInputStream is = new DataInputStream(new ByteArrayInputStream(data));
  52. innerPid = is.readInt();
  53. }
  54. if (innerPid == -1) {
  55. Log.w(TAG, "Error reading pid from wrapped process, child may have died");
  56. }
  57. } catch (Exception ex) {
  58. Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);
  59. }
  60. // Ensure that the pid reported by the wrapped process is either the
  61. // child process that we forked, or a descendant of it.
  62. if (innerPid > 0) {
  63. int parentPid = innerPid;
  64. while (parentPid > 0 && parentPid != pid) {
  65. parentPid = Process.getParentPid(parentPid);
  66. }
  67. if (parentPid > 0) {
  68. Log.i(TAG, "Wrapped process has pid " + innerPid);
  69. pid = innerPid;
  70. usingWrapper = true;
  71. } else {
  72. Log.w(TAG, "Wrapped process reported a pid that is not a child of "
  73. + "the process that we forked: childPid=" + pid
  74. + " innerPid=" + innerPid);
  75. }
  76. }
  77. }
  78. try {
  79. mSocketOutStream.writeInt(pid);
  80. mSocketOutStream.writeBoolean(usingWrapper);
  81. } catch (IOException ex) {
  82. throw new IllegalStateException("Error writing to command socket", ex);
  83. }
  84. }

主要进行一些资源清理的工作。到这里,子进程就创建完成了。

总结

  1. 调用 Process.start() 创建应用进程
  2. ZygoteProcess 负责和 Zygote 进程建立 socket 连接,并将创建进程需要的参数发送给 Zygote 的 socket 服务端
  3. Zygote 服务端接收到参数之后调用 ZygoteConnection.processOneCommand() 处理参数,并 fork 进程
  4. 最后通过 findStaticMain() 找到 ActivityThread 类的 main() 方法并执行,子进程就启动了

预告

到现在为止已经解析了 Zygote 进程 ,SystemServer 进程,以及应用进程的创建。下一篇的内容是和应用最密切相关的系统服务 ActivityManagerService , 来看看它在 SystemServer 中是如何被创建和启动的,敬请期待!

文章首发微信公众号: 秉心说 , 专注 Java 、 Android 原创知识分享,LeetCode 题解。

更多最新原创文章,扫码关注我吧!

原文链接:http://www.cnblogs.com/bingxinshuo/p/11681943.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号