Android应用进程创建解析

    通过之前博客的介绍,我们知道所有的android应用程序进程都是由Zygote创建的。Zygote进程通过复制自身的方法来创建一个新的应用程序进程。这样创建的新的应用程序进程就会获得一个虚拟机实例,有了这个虚拟机实例之后,这个应用程序进程就可以将Java开发的应用程序组件运行起来。应用程序进程在创建的时候除了获得一个虚拟机实例之外,还可以获得一个binder线程池和一个消息循环。这样运行在它里面的应用程序就可以方便的使用Android系统的消息处理机制和Binder通信机制。

    整个应用进程的创建流程如下图所示:

                                

    整个过程包含4个部分:

    1.App发起进程:一个App进程可以通过startActivity等系统API请求SystemServer进程创建进程。创建进程的请求通过binder发送。

    2.system_server进程:调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求;

    3.zygote进程:在之前博客中介绍过,当Zygote进程创建的时候就会创建一个LocalServerSocket,然后无限循环等待客户端发送创建新进程的Socket请求。当有客户端请求时,建立连接,然后执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程;

    4.新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法。

    整个过程的时序图如下所示,下面我们来一步步具体分析。

    我们在之前Activity启动分析的博客中也描述过进程创建的流程,所以这边APP向AMS发送创建进程的细节我们就不再描述,有兴趣的同学可以翻看之前的博客。这里我们直接从SystemServer向Zygote发送创建新进程的请求看起。

//frameworks/base/services/core/java/com/android/server/am/ProcessList.java
1619              final String entryPoint = "android.app.ActivityThread";

//processClass等于entryPoint,这个参数会一路传递下去,最后通过反射调用ActivityThread中main函数
521      public static ProcessStartResult start(@NonNull final String processClass,
522                                             @Nullable final String niceName,
523                                             int uid, int gid, @Nullable int[] gids,
524                                             int runtimeFlags,
525                                             int mountExternal,
526                                             int targetSdkVersion,
527                                             @Nullable String seInfo,
528                                             @NonNull String abi,
529                                             @Nullable String instructionSet,
530                                             @Nullable String appDataDir,
531                                             @Nullable String invokeWith,
532                                             @Nullable String packageName,
533                                             @Nullable String[] zygoteArgs) {
534          return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
535                      runtimeFlags, mountExternal, targetSdkVersion, seInfo,
536                      abi, instructionSet, appDataDir, invokeWith, packageName,
537                      /*useUsapPool=*/ true, zygoteArgs);
538      }


//frameworks/base/core/java/android/os/ZygoteProcess.java
314      public final Process.ProcessStartResult start(@NonNull final String processClass,
315                                                    final String niceName,
316                                                    int uid, int gid, @Nullable int[] gids,
317                                                    int runtimeFlags, int mountExternal,
318                                                    int targetSdkVersion,
319                                                    @Nullable String seInfo,
320                                                    @NonNull String abi,
321                                                    @Nullable String instructionSet,
322                                                    @Nullable String appDataDir,
323                                                    @Nullable String invokeWith,
324                                                    @Nullable String packageName,
325                                                    boolean useUsapPool,
326                                                    @Nullable String[] zygoteArgs) {
327          // TODO (chriswailes): Is there a better place to check this value?
328          if (fetchUsapPoolEnabledPropWithMinInterval()) {
329              informZygotesOfUsapPoolStatus();
330          }
331  
332          try {
333              return startViaZygote(processClass, niceName, uid, gid, gids,
334                      runtimeFlags, mountExternal, targetSdkVersion, seInfo,
335                      abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
336                      packageName, useUsapPool, zygoteArgs);
337          } catch (ZygoteStartFailedEx ex) {
338              Log.e(LOG_TAG,
339                      "Starting VM process through Zygote failed");
340              throw new RuntimeException(
341                      "Starting VM process through Zygote failed", ex);
342          }
343      }

        start函数中只调用了startViaZygote函数。

//frameworks/base/core/java/android/os/ZygoteProcess.java
541      private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
542                                                        @Nullable final String niceName,
543                                                        final int uid, final int gid,
544                                                        @Nullable final int[] gids,
545                                                        int runtimeFlags, int mountExternal,
546                                                        int targetSdkVersion,
547                                                        @Nullable String seInfo,
548                                                        @NonNull String abi,
549                                                        @Nullable String instructionSet,
550                                                        @Nullable String appDataDir,
551                                                        @Nullable String invokeWith,
552                                                        boolean startChildZygote,
553                                                        @Nullable String packageName,
554                                                        boolean useUsapPool,
555                                                        @Nullable String[] extraArgs)
556                                                        throws ZygoteStartFailedEx {
557          ArrayList<String> argsForZygote = new ArrayList<>();
558  
559          // --runtime-args, --setuid=, --setgid=,
560          // and --setgroups= must go first
561          argsForZygote.add("--runtime-args");
562          argsForZygote.add("--setuid=" + uid);
563          argsForZygote.add("--setgid=" + gid);
564          argsForZygote.add("--runtime-flags=" + runtimeFlags);
565          if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
566              argsForZygote.add("--mount-external-default");
567          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
568              argsForZygote.add("--mount-external-read");
569          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
570              argsForZygote.add("--mount-external-write");
571          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
572              argsForZygote.add("--mount-external-full");
573          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
574              argsForZygote.add("--mount-external-installer");
575          } else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
576              argsForZygote.add("--mount-external-legacy");
577          }
578  
579          argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
580  
581          // --setgroups is a comma-separated list
582          if (gids != null && gids.length > 0) {
583              StringBuilder sb = new StringBuilder();
584              sb.append("--setgroups=");
585  
586              int sz = gids.length;
587              for (int i = 0; i < sz; i++) {
588                  if (i != 0) {
589                      sb.append(',');
590                  }
591                  sb.append(gids[i]);
592              }
593  
594              argsForZygote.add(sb.toString());
595          }
596  
597          if (niceName != null) {
598              argsForZygote.add("--nice-name=" + niceName);
599          }
600  
601          if (seInfo != null) {
602              argsForZygote.add("--seinfo=" + seInfo);
603          }
604  
605          if (instructionSet != null) {
606              argsForZygote.add("--instruction-set=" + instructionSet);
607          }
608  
609          if (appDataDir != null) {
610              argsForZygote.add("--app-data-dir=" + appDataDir);
611          }
612  
613          if (invokeWith != null) {
614              argsForZygote.add("--invoke-with");
615              argsForZygote.add(invokeWith);
616          }
617  
618          if (startChildZygote) {
619              argsForZygote.add("--start-child-zygote");
620          }
621  
622          if (packageName != null) {
623              argsForZygote.add("--package-name=" + packageName);
624          }
625  
626          argsForZygote.add(processClass);
             //上面是将启动应用进程的启动参数保存在argsForZygote中
627  
628          if (extraArgs != null) {
629              Collections.addAll(argsForZygote, extraArgs);
630          }
631  
632          synchronized(mLock) {
633              // The USAP pool can not be used if the application will not use the systems graphics
634              // driver.  If that driver is requested use the Zygote application start path.
                 //请求zygote fork进程,zygoteSendArgsAndGetResult函数中第一个参数中调用了
                 //openZygoteSocketIfNeeded函数,而第二个参数是保存应用进程的启动参数
635              return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
636                                                useUsapPool,
637                                                argsForZygote);
638          }
639      }

    我们先看下openZygoteSocketIfNeeded。

//frameworks/base/core/java/android/os/ZygoteProcess.java
906      private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
907          try {
                 //尝试与zygote建立连接
908              attemptConnectionToPrimaryZygote();
909
                 //根据当前的abi来选择与zygote还是zygote64来进行通信
910              if (primaryZygoteState.matches(abi)) {
911                  return primaryZygoteState;
912              }
913  
914              if (mZygoteSecondarySocketAddress != null) {
915                  // The primary zygote didn't match. Try the secondary.
916                  attemptConnectionToSecondaryZygote();
917  
                     根据当前的abi来选择与zygote还是zygote64来进行通信
918                  if (secondaryZygoteState.matches(abi)) {
919                      return secondaryZygoteState;
920                  }
921              }
922          } catch (IOException ioe) {
923              throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
924          }
925  
926          throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
927      }

       在之前Zygote进程启动博客中过程时我们得知,Zygote进程有两个Socket,这里当主zygote没能匹配成功,则尝试第二个mSecondarySocket来连接。这两个Socket区别就是:name为”zygote”的Socket是运行在64位Zygote进程中的,而name为“zygote_secondary”的Socket则运行在32位Zygote进程中。既然应用程序进程是通过Zygote进程fock产生的,当要连接Zygote中的Socket时,也需要保证位数的一致。具体的连接过程如下:

//frameworks/base/core/java/android/os/ZygoteProcess.java
872      private void attemptConnectionToPrimaryZygote() throws IOException {
873          if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
874              primaryZygoteState =
875                      ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
876  
877              maybeSetApiBlacklistExemptions(primaryZygoteState, false);
878              maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
879              maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);
880          }
881      }

175          static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
176                  @Nullable LocalSocketAddress usapSocketAddress)
177                  throws IOException {
178  
179              DataInputStream zygoteInputStream;
180              BufferedWriter zygoteOutputWriter;
181              final LocalSocket zygoteSessionSocket = new LocalSocket();
182  
183              if (zygoteSocketAddress == null) {
184                  throw new IllegalArgumentException("zygoteSocketAddress can't be null");
185              }
186  
187              try {
188                  zygoteSessionSocket.connect(zygoteSocketAddress);
189                  zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
190                  zygoteOutputWriter =
191                          new BufferedWriter(
192                                  new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),
193                                  Zygote.SOCKET_BUFFER_SIZE);
194              } catch (IOException ex) {
195                  try {
196                      zygoteSessionSocket.close();
197                  } catch (IOException ignore) { }
198  
199                  throw ex;
200              }
201  
202              return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
203                                     zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
204                                     getAbiList(zygoteOutputWriter, zygoteInputStream));
205          }

    这个方法主要是创建了LocalSocket,与Zygote进程的LocalServerSocket成功连接之后,获取这个LocalSocket的输入流zygoteInputStream与输出流zygoteWriter,并且将他们封装到ZygoteState中再返回。我们将返回的ZygoteState作为参数,传递到zygoteSendArgsAndGetResult函数中去执行。

//frameworks/base/core/java/android/os/ZygoteProcess.java
381      private Process.ProcessStartResult zygoteSendArgsAndGetResult(
382              ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)
383              throws ZygoteStartFailedEx {
384          // Throw early if any of the arguments are malformed. This means we can
385          // avoid writing a partial response to the zygote.
386          for (String arg : args) {
387              // Making two indexOf calls here is faster than running a manually fused loop due
388              // to the fact that indexOf is a optimized intrinsic.
389              if (arg.indexOf('\n') >= 0) {
390                  throw new ZygoteStartFailedEx("Embedded newlines not allowed");
391              } else if (arg.indexOf('\r') >= 0) {
392                  throw new ZygoteStartFailedEx("Embedded carriage returns not allowed");
393              }
394          }
395  
396          /*
397           * See com.android.internal.os.ZygoteArguments.parseArgs()
398           * Presently the wire format to the zygote process is:
399           * a) a count of arguments (argc, in essence)
400           * b) a number of newline-separated argument strings equal to count
401           *
402           * After the zygote process reads these it will write the pid of
403           * the child or -1 on failure, followed by boolean to
404           * indicate whether a wrapper process was used.
405           */
406          String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
407  
408          if (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {
409              try {
410                  return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
411              } catch (IOException ex) {
412                  // If there was an IOException using the USAP pool we will log the error and
413                  // attempt to start the process through the Zygote.
414                  Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
415                          + ex.getMessage());
416              }
417          }
418  
419          return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
420      }


451      private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
452              ZygoteState zygoteState, String msgStr)
453              throws ZygoteStartFailedEx, IOException {
454          try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
455              final BufferedWriter usapWriter =
456                      new BufferedWriter(
457                              new OutputStreamWriter(usapSessionSocket.getOutputStream()),
458                              Zygote.SOCKET_BUFFER_SIZE);
459              final DataInputStream usapReader =
460                      new DataInputStream(usapSessionSocket.getInputStream());
461  
                 把应用进程的一些参数写给前面连接的zygote进程,包括前面的
                 //processClass ="android.app.ActivityThread"
462              usapWriter.write(msgStr);
463              usapWriter.flush();
464  
                 创建Process.ProcessStartResult用于存放fork进程的返回结果
465              Process.ProcessStartResult result = new Process.ProcessStartResult();
                 //从socket中得到zygote创建的应用pid
466              result.pid = usapReader.readInt();
467              // USAPs can't be used to spawn processes that need wrappers.
468              result.usingWrapper = false;
469  
                 //通过pid判断是否创建成功
470              if (result.pid >= 0) {
471                  return result;
472              } else {
473                  throw new ZygoteStartFailedEx("USAP specialization failed");
474              }
475          }
476      }

    这段代码主要是和Server端的Zygote进程的LocketServerSocket进行通信。将AMS中创建进程的参数传递给Zygote进程。Zygote进程fork完成之后, readInt()就能读取出返回结果,如果小于0,代表创建失败,不小于0代表创建成功。

    至此我们完成了Socket Client端的工作,我们将创建进程的请求通过Socket发送给了 Socket的server端Zygote。我们再之前Zygote启动的博客中介绍过,Zygotefork出SystemServer进程之后,就会进入一个无限循环等待,用来接收Socket发来的消息,fork出其他应用进程。我们来看下Zygote这一部分的具体流程。

//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
819      public static void main(String argv[]) {
820          ZygoteServer zygoteServer = null;
821  
822          // Mark zygote start. This ensures that thread creation will throw
823          // an error.
824          ZygoteHooks.startZygoteNoThreadCreation();
         ........
                 //调用ZygoteServer构造函数,创建Server端socket,详情见5.2
900              zygoteServer = new ZygoteServer(isPrimaryZygote);
         ........
                 //启动一个循环监听来自Client端的消息
917              caller = zygoteServer.runSelectLoop(abiList);
918          } catch (Throwable ex) {
919              Log.e(TAG, "System zygote died with exception", ex);
920              throw ex;
921          } finally {
922              if (zygoteServer != null) {
923                  zygoteServer.closeServerSocket();
924              }
925          }
926  
927          // We're in the child process and have exited the select loop. Proceed to execute the
928          // command.
929          if (caller != null) {
930              caller.run();
931          }
932      }

    这部分内容在Zygote启动博客中具体解释过,这里为了更好理解简单再讲解一下,new ZygoteServer(isPrimaryZygote)会创建Server端的Socket,它用来等待ActivityManagerService请求Zygote来创建新的应用程序进程。最后调用runSelectLoop函数来等待ActivityManagerService的请求。我们就来查看runSelectLoop函数:

//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
373      Runnable runSelectLoop(String abiList) {
374          ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
375          ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
         ..........

439              while (--pollIndex >= 0) {
440                  if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
441                      continue;
442                  }
443  
                     //当pollIndex为0的时候,代表有客户端连接请求。
                     //创建ZygoteConnection,创建LocalServerSocket
444                  if (pollIndex == 0) {
445                      // Zygote server socket
446  
447                      ZygoteConnection newPeer = acceptCommandPeer(abiList);
448                      peers.add(newPeer);
449                      socketFDs.add(newPeer.getFileDescriptor());
450  
451                  } else if (pollIndex < usapPoolEventFDIndex) {
452                      // Session socket accepted from the Zygote server socket
453  
454                      try {
455                          ZygoteConnection connection = peers.get(pollIndex);
                             //通过socket接收来自对端的数据,执行processOneCommand
456                          final Runnable command = connection.processOneCommand(this);
457  
458                          // TODO (chriswailes): Is this extra check necessary?
459                          if (mIsForkChild) {
460                              // We're in the child. We should always have a command to run at this
461                              // stage if processOneCommand hasn't called "exec".
462                              if (command == null) {
463                                  throw new IllegalStateException("command == null");
464                              }
465  
466                              return command;
467                          } else {
468                              // We're in the server - we should never have any commands to run.
469                              if (command != null) {
470                                  throw new IllegalStateException("command != null");
471                              }
472  
473                              // We don't know whether the remote side of the socket was closed or
474                              // not until we attempt to read from it from processOneCommand. This
475                              // shows up as a regular POLLIN event in our regular processing loop.
476                              if (connection.isClosedByPeer()) {
477                                  connection.closeSocket();
478                                  peers.remove(pollIndex);
479                                  socketFDs.remove(pollIndex);
480                              }
481                          }

            ..............

    我们首先建立Socket Clinet端和Server端的连接。

//frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
196      private ZygoteConnection acceptCommandPeer(String abiList) {
197          try {
198              return createNewConnection(mZygoteSocket.accept(), abiList);
199          } catch (IOException ex) {
200              throw new RuntimeException(
201                      "IOException during accept()", ex);
202          }
203      }
205      protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList)
206              throws IOException {
207          return new ZygoteConnection(socket, abiList);
208      }

//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
90      ZygoteConnection(LocalSocket socket, String abiList) throws IOException {
91          mSocket = socket;
92          this.abiList = abiList;
93  
94          mSocketOutStream
95                  = new DataOutputStream(socket.getOutputStream());
96  
97          mSocketReader = new BufferedReader(
98                  new InputStreamReader(socket.getInputStream()), 256);
99  
100          mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);
101  
102          try {
103              peer = mSocket.getPeerCredentials();
104          } catch (IOException ex) {
105              Log.e(TAG, "Cannot read peer credentials", ex);
106              throw ex;
107          }
108  
109          isEof = false;
110      }

    acceptCommandPeer中调用createNewConnection,返回值是一个ZygoteConnection,封装了mServerSocket的输入流mSocketReader与输出流mSocketOutStream,这个与Clinet端的ZygoteState类似。

    在ZygoteConnection创建好了之后,就执行processOneCommand真正处理进程的创建请求了。

//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
129      Runnable processOneCommand(ZygoteServer zygoteServer) {
         ........
             //Fork子进程,得到一个新的pid
             //fork子进程,采用copy on write方式,这里执行一次,会返回两次
             //pid=0 表示Zygote  fork子进程成功
             //pid > 0 表示子进程 的真正的PI
267          pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
268                  parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
269                  parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
270                  parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
271  
272          try {
273              if (pid == 0) {
274                  // in child
                     //pid==0代表是新创建的子进程
275                  zygoteServer.setForkChild();
276  
277                  zygoteServer.closeServerSocket();
278                  IoUtils.closeQuietly(serverPipeFd);
279                  serverPipeFd = null;
280  
281                  return handleChildProc(parsedArgs, descriptors, childPipeFd,
282                          parsedArgs.mStartChildZygote);
283              } else {
                     //大于0,是父进程,也就是Zygote进程
284                  // In the parent. A pid < 0 indicates a failure and will be handled in
285                  // handleParentProc.
286                  IoUtils.closeQuietly(childPipeFd);
287                  childPipeFd = null;
288                  handleParentProc(pid, descriptors, serverPipeFd);
289                  return null;
290              }
291          } finally {
292              IoUtils.closeQuietly(childPipeFd);
293              IoUtils.closeQuietly(serverPipeFd);
294          }
295      }


//frameworks/base/core/java/com/android/internal/os/Zygote.java
234      public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
235              int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
236              int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
237              int targetSdkVersion) {
238          ZygoteHooks.preFork();
239          // Resets nice priority for zygote process.
240          resetNicePriority();
             //jni调用,fork新的进程
241          int pid = nativeForkAndSpecialize(
242                  uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
243                  fdsToIgnore, startChildZygote, instructionSet, appDataDir);
244          // Enable tracing as soon as possible for the child process.
245          if (pid == 0) {
246              Zygote.disableExecuteOnly(targetSdkVersion);
247              Trace.setTracingEnabled(true, runtimeFlags);
248  
249              // Note that this event ends at the end of handleChildProc,
250              Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
251          }
252          ZygoteHooks.postForkCommon();
253          return pid;
254      }

    当forkAndSpecialize完成之后,进程就被创建出来了,还需要handleChildProc方法继续对进程做一些处理。

560      private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
561              FileDescriptor pipeFd, boolean isZygote) {
         ........
597          } else {
598              if (!isZygote) {
                     //进程初始化操作
599                  return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
600                          parsedArgs.mRemainingArgs, null /* classLoader */);
601              } else {
602                  return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
603                          parsedArgs.mRemainingArgs, null /* classLoader */);
604              }
605          }
606      }


//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
972      public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
973              ClassLoader classLoader) {
974          if (RuntimeInit.DEBUG) {
975              Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
976          }
977  
978          Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
979          RuntimeInit.redirectLogStreams();
980          
             //通用初始化设置
981          RuntimeInit.commonInit();
             //启动binder线程池
982          ZygoteInit.nativeZygoteInit();
             //应用初始化
983          return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
984      }

        启动bidner线程池和systemServer启动博客中分析过,详情如下:

//JNI调用com_android_internal_os_ZygoteInit_nativeZygoteInit
//frameworks/base/core/jni/AndroidRuntime.cpp
295  int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
296  {
297      const JNINativeMethod methods[] = {
298          { "nativeZygoteInit", "()V",
299              (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
300      };
301      return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
302          methods, NELEM(methods));
303  }
 
268  static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
269  {
270      gCurRuntime->onZygoteInit();
271  }
 
//frameworks/base/cmds/app_process/app_main.cpp
92      virtual void onZygoteInit()
93      {
94          sp<ProcessState> proc = ProcessState::self();
95          ALOGV("App process: starting thread pool.\n");
96          proc->startThreadPool();//启动binder线程池
97      }

    最后看下applicationInit。

//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
343      protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
344              ClassLoader classLoader) {
345          // If the application calls System.exit(), terminate the process
346          // immediately without running any shutdown hooks.  It is not possible to
347          // shutdown an Android application gracefully.  Among other things, the
348          // Android runtime shutdown hooks close the Binder driver, which can cause
349          // leftover running threads to crash before the process actually exits.
350          nativeSetExitWithoutCleanup(true);
351  
352          // We want to be fairly aggressive about heap utilization, to avoid
353          // holding on to a lot of memory that isn't needed.
 
             //设置虚拟机的内存利用率参数值为0.75
354          VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
355          VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
356  
357          final Arguments args = new Arguments(argv);
358  
359          // The end of of the RuntimeInit event (see #zygoteInit).
360          Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
361  
362          // Remaining arguments are passed to the start class's static main
             //经过applicationInit中的Arguments构造方法,args.startClass的值就是android.app.ActivityThread.java。
363          return findStaticMain(args.startClass, args.startArgs, classLoader);
364      }
 
284      protected static Runnable findStaticMain(String className, String[] argv,
285              ClassLoader classLoader) {
286          Class<?> cl;
287  
288          try {
                 //拿到android.app.ActivityThread.java的类对象
289              cl = Class.forName(className, true, classLoader);
290          } catch (ClassNotFoundException ex) {
291              throw new RuntimeException(
292                      "Missing class when invoking static main " + className,
293                      ex);
294          }
295  
296          Method m;
297          try {
                 //得到ActivityThread的main()方法
298              m = cl.getMethod("main", new Class[] { String[].class });
299          } catch (NoSuchMethodException ex) {
300              throw new RuntimeException(
301                      "Missing static main on " + className, ex);
302          } catch (SecurityException ex) {
303              throw new RuntimeException(
304                      "Problem getting static main on " + className, ex);
305          }
306  
307          int modifiers = m.getModifiers();
308          if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
309              throw new RuntimeException(
310                      "Main method is not public and static on " + className);
311          }
312  
313          /*
314           * This throw gets caught in ZygoteInit.main(), which responds
315           * by invoking the exception's run() method. This arrangement
316           * clears up all the stack frames that were required in setting
317           * up the process.
318           */

319          return new MethodAndArgsCaller(m, argv);
320      }
 
478      static class MethodAndArgsCaller implements Runnable {
479          /** method to call */
480          private final Method mMethod;
481  
482          /** argument array */
483          private final String[] mArgs;
484  
485          public MethodAndArgsCaller(Method method, String[] args) {
486              mMethod = method;
487              mArgs = args;
488          }
489  
490          public void run() {
491              try {
                     根据传递过来的参数,可知此处通过反射机制调用的是ActivityThread.main()方法
492                  mMethod.invoke(null, new Object[] { mArgs });
493              } catch (IllegalAccessException ex) {
494                  throw new RuntimeException(ex);
495              } catch (InvocationTargetException ex) {
496                  Throwable cause = ex.getCause();
497                  if (cause instanceof RuntimeException) {
498                      throw (RuntimeException) cause;
499                  } else if (cause instanceof Error) {
500                      throw (Error) cause;
501                  }
502                  throw new RuntimeException(ex);
503              }
504          }
505      }
506  }

    这个地方和systemServer的启动异曲同工,通过反射来获得android.app.ActivityThread类,接下来获得ActivityThread的main函数,并将main函数传入到MethodAndArgsCaller类的构造函数中,MethodAndArgsCaller类内部会通过反射调用ActivityThread的main函数,这样应用程序进程就创建完成了。

                         


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值