由于四大组件的启动都涉及到进程的启动,因此我们这章先讲一下进程启动流程,然后再讲四大组件的启动流程。
 
 
基础知识 Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制;这两个特点都是在进程的初始化过程中实现的。(引用自老罗安卓之旅-Android应用程序进程启动过程的源代码分析 )
进程按照重要性可以分为下面五类:
前台进程(Foreground process) 
可见进程(Visible process) 
服务进程(Service process) 
后台进程(Background process) 
空进程(Empty process) 
 
进程启动流程 AMS(ActivityMagagerService)启动进程是从其成员函数startProcessLocked开始调用Process.start方法开始的。我们先看一下进程启动的时序图:
1. Process.start方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  static  final  ProcessStartResult start (final  String processClass,                                                  final  String niceName,                                                  int  uid, int  gid, int [] gids,                                                  int  debugFlags, int  mountExternal,                                                  int  targetSdkVersion,                                                  String seInfo,                                                  String abi,                                                  String instructionSet,                                                  String appDataDir,                                                  String[] zygoteArgs)  {    try  {                  return  startViaZygote(processClass, niceName, uid, gid, gids,                 debugFlags, mountExternal, targetSdkVersion, seInfo,                 abi, instructionSet, appDataDir, zygoteArgs);      } catch  (ZygoteStartFailedEx ex) {         Log.e(LOG_TAG,                 "Starting VM process through Zygote failed" );         throw  new  RuntimeException (                 "Starting VM process through Zygote failed" , ex);      } } 
 
注意:传入的第一个参数是“android.app.ActivityThread”,这是进程初始化要加载的类,这个类加载到进程之后,就会把这个类的静态成员方法main作为进程的入口。然后调用startViaZygote方法。
2. startViaZygote方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 private  static  ProcessStartResult startViaZygote (final  String processClass,                                                      final  String niceName,                                                      final  int  uid, final  int  gid,                                                      final  int [] gids,                                                      int  debugFlags, int  mountExternal,                                                      int  targetSdkVersion,                                                      String seInfo,                                                      String abi,                                                      String instructionSet,                                                      String appDataDir,                                                      String[] extraArgs)             throws  ZygoteStartFailedEx {         synchronized  (Process.class) {             ArrayList<String> argsForZygote = new  ArrayList <String>();                          ...                          ...                          ...                          return  zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);         }     } 
 
这个方法主要是保存信息到argsForZygote中,然后调用openZygoteSocketIfNeeded,然后根据返回的值调用zygoteSendArgsAndGetResult方法,首先先看openZygoteSocketIfNeeded方法。
3. openZygoteSocketIfNeeded方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 private  static  ZygoteState openZygoteSocketIfNeeded (String abi)  throws  ZygoteStartFailedEx {        if  (primaryZygoteState == null  || primaryZygoteState.isClosed()) {             try  {                                  primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);             } catch  (IOException ioe) {                 throw  new  ZygoteStartFailedEx ("Error connecting to primary zygote" , ioe);             }         }         if  (primaryZygoteState.matches(abi)) {             return  primaryZygoteState;         }                  if  (secondaryZygoteState == null  || secondaryZygoteState.isClosed()) {             try  {                                  secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);             } catch  (IOException ioe) {                 throw  new  ZygoteStartFailedEx ("Error connecting to secondary zygote" , ioe);             }         }         if  (secondaryZygoteState.matches(abi)) {             return  secondaryZygoteState;         }         throw  new  ZygoteStartFailedEx ("Unsupported zygote ABI: "  + abi);     } 
 
通过ZygoteState.connect放创建primaryZygoteState对象,如果第一次创建不成功,创建第二次。connect方法代码如下:
4. ZygoteState.connect方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public  static  ZygoteState connect (String socketAddress)  throws  IOException {            DataInputStream  zygoteInputStream  =  null ;             BufferedWriter  zygoteWriter  =  null ;                          final  LocalSocket  zygoteSocket  =  new  LocalSocket ();             try  {                                                                    zygoteSocket.connect(new  LocalSocketAddress (socketAddress,                         LocalSocketAddress.Namespace.RESERVED));                                                   zygoteInputStream = new  DataInputStream (zygoteSocket.getInputStream());                                                   zygoteWriter = new  BufferedWriter (new  OutputStreamWriter (                         zygoteSocket.getOutputStream()), 256 );             } catch  (IOException ex) {                 ...             }             String  abiListString  =  getAbiList(zygoteWriter, zygoteInputStream);             Log.i("Zygote" , "Process: zygote socket opened, supported ABIS: "  + abiListString);                          return  new  ZygoteState (zygoteSocket, zygoteInputStream, zygoteWriter,                     Arrays.asList(abiListString.split("," )));         } 
 
首先创建一个LocalSocket对象,这个LocalSocket对象是在ZygoteInit中的runSelectLoop函数进行监听的。然后通过connect方法并且传入连接地址连接该Socket,连接以后会获取输入流DataInputStream,以便获得Zygote进程发送过来的通信数据,然后又获取BufferedWriter输入流,以便向Zygote进程发送通信数据。最后会返回一个ZygoteState对象。下面我们看一下LocalSocket.connect方法。
5. LocalSocket.connect方法: 1 2 3 4 5 6 7 8 9 10 11 12 public  void  connect (LocalSocketAddress endpoint)  throws  IOException {    synchronized  (this ) {         if  (isConnected) {             throw  new  IOException ("already connected" );         }         implCreateIfNeeded();         impl.connect(endpoint, 0 );         isConnected = true ;         isBound = true ;     } } 
 
如果已经连接,抛出异常,因为连接完成后,会关闭连接,使用时在打开连接。最后调用native方法连接socket,并且改变连接标签。
6. 回到第二步,调用完openZygoteSocketIfNeeded返回参数ZygoteState传入到zygoteSendArgsAndGetResult方法中: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 private  static  ProcessStartResult zygoteSendArgsAndGetResult (         ZygoteState zygoteState, ArrayList<String> args)         throws  ZygoteStartFailedEx {     try  {                           int  sz  =  args.size();         for  (int  i  =  0 ; i < sz; i++) {             if  (args.get(i).indexOf('\n' ) >= 0 ) {                 throw  new  ZygoteStartFailedEx ("embedded newlines not allowed" );             }         }         final  BufferedWriter  writer  =  zygoteState.writer;         final  DataInputStream  inputStream  =  zygoteState.inputStream;         writer.write(Integer.toString(args.size()));         writer.newLine();         for  (int  i  =  0 ; i < sz; i++) {             String  arg  =  args.get(i);             writer.write(arg);             writer.newLine();         }         writer.flush();                                    ProcessStartResult  result  =  new  ProcessStartResult ();                                    result.pid = inputStream.readInt();         result.usingWrapper = inputStream.readBoolean();         if  (result.pid < 0 ) {             throw  new  ZygoteStartFailedEx ("fork() failed" );         }         return  result;     } catch  (IOException ex) {         zygoteState.close();         throw  new  ZygoteStartFailedEx (ex);     } } 
 
这方法通过Socket流的方式将启动进程的信息发送出去,从步骤4可知,这个Socket的监听是ZygoteInit类中的runSelectLoop方法,我们接着看这个方法。
7. ZygoteInit.runSelectLoop方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 private  static  void  runSelectLoop (String abiList)  throws  MethodAndArgsCaller {    ArrayList<FileDescriptor> fds = new  ArrayList <FileDescriptor>();     ArrayList<ZygoteConnection> peers = new  ArrayList <ZygoteConnection>();     fds.add(sServerSocket.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 ) {                 ZygoteConnection  newPeer  =  acceptCommandPeer(abiList);                 peers.add(newPeer);                 fds.add(newPeer.getFileDesciptor());             } else  {                 boolean  done  =  peers.get(i).runOnce();                 if  (done) {                     peers.remove(i);                     fds.remove(i);                 }             }         }     } } 
 
数据通过Socket发送以后,Zygote进程接收到后会调用peers.get(i).runOnce()方法。这个peers.get(i)是获取ZygoteConnection对象,表示一个Socket连接,然后调用它的runOnce方法。
8. ZygoteConnection.runOnce方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 boolean  runOnce ()  throws  ZygoteInit.MethodAndArgsCaller {    String args[];     Arguments  parsedArgs  =  null ;     FileDescriptor[] descriptors;     try  {                  args = readArgumentList();         descriptors = mSocket.getAncillaryFileDescriptors();     } catch  (IOException ex) {         Log.w(TAG, "IOException on command socket "  + ex.getMessage());         closeSocket();         return  true ;     }     ...          PrintStream  newStderr  =  null ;     if  (descriptors != null  && descriptors.length >= 3 ) {         newStderr = new  PrintStream (                 new  FileOutputStream (descriptors[2 ]));     }     int  pid  =  -1 ;     FileDescriptor  childPipeFd  =  null ;     FileDescriptor  serverPipeFd  =  null ;     try  {         parsedArgs = new  Arguments (args);         if  (parsedArgs.abiListQuery) {             return  handleAbiListQuery();         }         ...                                    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 ) {             ...             handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);             return  true ;         } else  {             ...             return  handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);         }     } finally  {         ...     } } 
 
首先通过Zygote.forkAndSpecialize方法来创建一个新的进程,并且返回其pid。因为我们在分心新建进程,因此我们只分析pid为0的情况,pid为0时会调用handleChildProc方法,
9. handleChildProc方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private  void  handleChildProc (Arguments parsedArgs,         FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)         throws  ZygoteInit.MethodAndArgsCaller {     ...          Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);     if  (parsedArgs.invokeWith != null ) {         WrapperInit.execApplication(parsedArgs.invokeWith,                 parsedArgs.niceName, parsedArgs.targetSdkVersion,                 VMRuntime.getCurrentInstructionSet(),                 pipeFd, parsedArgs.remainingArgs);     } else  {                  RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,                 parsedArgs.remainingArgs, null  );     } } 
 
由于我们之前加入参数是没有parsedArgs.invokeWith这个参数,因此这里是null,因此会走else里面的代码,执行RuntimeInit.zygoteInit方法。
10. RuntimeInit.zygoteInit方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 public  static  final  void  zygoteInit (int  targetSdkVersion, String[] argv, ClassLoader classLoader)         throws  ZygoteInit.MethodAndArgsCaller {     if  (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote" );     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit" );     redirectLogStreams();          commonInit();          nativeZygoteInit();     applicationInit(targetSdkVersion, argv, classLoader); } 
 
首先调用nativeZygoteInit函数,这是一个native函数,函数的目的是在新创建的应用程序进程中启动一个Binder线程池然后进行进程间通信。然后调用applicationInit函数
11. applicationInit函数: 1 2 3 4 5 6 7 8 9 private  static  void  applicationInit (int  targetSdkVersion, String[] argv, ClassLoader classLoader)         throws  ZygoteInit.MethodAndArgsCaller {     ...                    invokeStaticMain(args.startClass, args.startArgs, classLoader); } 
 
我们在前面讲过args.startClass传入进来的是”android.app.ActivityThread”,表示要执行”android.app.ActivityThread”的main函数。
12. invokeStaticMain函数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 private  static  void  invokeStaticMain (String className, String[] argv, ClassLoader classLoader)         throws  ZygoteInit.MethodAndArgsCaller {     Class<?> cl;     try  {         cl = Class.forName(className, true , classLoader);     } catch  (ClassNotFoundException ex) {         ...     }     Method m;     try  {                  m = cl.getMethod("main" , new  Class [] { String[].class });     } catch  (NoSuchMethodException ex) {         ...     } catch  (SecurityException ex) {         ...     }     ...          throw  new  ZygoteInit .MethodAndArgsCaller(m, argv);      } 
 
这个就是通过类加载器加载ActivityThread,然后调用起main方法。然后抛出异常,通过ZygoteInit中main函数中的catch来捕获异常。
13. ZygoteInit.main函数: 1 2 3 4 5 6 7 8 9 10 public  static  void  main (String argv[])  {    ...     } catch  (MethodAndArgsCaller caller) {                           caller.run();     } catch  (Throwable ex) {         ...     } } 
 
通过步骤12可知抛出的异常是MethodAndArgsCaller异常,因此会执行caller.run方法。
14. MethodAndArgsCaller.run: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public  void  run ()  {    try  {                  mMethod.invoke(null , new  Object []{mArgs});     } catch  (IllegalAccessException ex) {         throw  new  RuntimeException (ex);     } catch  (InvocationTargetException ex) {         Throwable  cause  =  ex.getCause();         if  (cause instanceof  RuntimeException) {             throw  (RuntimeException) cause;         } else  if  (cause instanceof  Error) {             throw  (Error) cause;         }         throw  new  RuntimeException (ex);     } } 
 
通过mMethod.invoke方法调用ActivityThread的main方法。
15. ActivityThread.mian方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public  static  void  main (String[] args)  {    ...          Looper.prepareMainLooper();     ActivityThread  thread  =  new  ActivityThread ();          thread.attach(false );     if  (sMainThreadHandler == null ) {                  sMainThreadHandler = thread.getHandler();     }     ...          Looper.loop();     throw  new  RuntimeException ("Main thread loop unexpectedly exited" ); } 
 
这里主要是创建该线程的looper,然后创建ActivityThread对象,然后进入消息循环。然后我们就可以启动Activity或者Service了。
代码地址: 直接拉取导入开发工具(Intellij idea或者Android studio)
Android_Framework_Source 
注 Android开发群:192508518
微信公众账号:Code-MX
注:本文原创,转载请注明出处,多谢。