根Activity的启动过程 根Activity 是应用程序第一个Activity,相比普通的Activity的启动过程,一般用根Activity 的启动过程来指代应用程序的启动过程,更具有参考意义。根Activity 的启动过程比较复杂,这里分为3个部分来讲:Launcher 请求AMS 过程、AMS 到ApplicaitonThread 的调用过程 以及 ActivityThread 启动Activity 。
Launcher 请求AMS 过程 当我们点击桌面上某个应用的快捷图标时,就会通过Launcher 请求AMS 来启动该应用程序,过程的时序图如下:
点击桌面图标,会调用 Launcher 的startActivitySafely方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public  boolean  startActivitySafely (View v ,Intent intent, Itemlnfo item)     ...     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);      try {         if  (xxxx){             ...         }else  if (user == null  || user.equals(Process.myUserHandle())){             startActivity(intent, optsBundle);          }else  {             ...         }         return  true ;     } catch  (ActivityNotFoundExceptionlSecurityException e) {         ...     }     return  false ; } 
因为是启动新的应用,所以注释1处将根Activity 在新的任务栈启动,应用启动会执行到注释2处的startActivity 方法,最终会在Activity 中调用  startActivityForResult 方法:
1 2 3 4 5 6 7 8 9 public  void  startActivityForResult (@RequiresPermission  Intent intent, int  requestCode, @Nullable  Bundle options)      if  (mParent == null ) {         options = transferSpringboardActivityOptions(options);         Instrumentation.ActivityResult ar = minstrumentation.execStartActivity(this , mMainThread.getApplicationThread(), mToke,this ,intent, requestCode , option);     } else  {         ...     } 
注释1的mParent 是Activity 类型,表示当前Activity 的父类(个人理解,这里应该说是当前Activity的前一个Activity),因此mParent == null 成立,最后由 Instrumentation 的execStartActivity方法来执行启动操作。 Instrumentation 主要用于监控应用程序和系统的交互。 主要代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 public  ActivityResult execStartActivity (Context who , IBinder contextThread, IBinder token , Activity target, Intent intent ,int  requestCode ,Bundle options) ... try  {    intent.migrateExtraStreamToClipData();     intent.prepareToLeaveProcess(who );     int  result = ActivityManager.getService().startActivity(xxx,xxx,xxxx));     checkStartActivityResult(result, intent); } catch  (RemoteException e) {     throw  new  RuntimeException("Failure from system" , e); } return  null ;
由代码可知,首先通过 ActivityManager 获取 AMS 的代理对象,接着调用代理对象的 startActivity 方法。AMS 的代理对象是一个 IActivityManager(该类由AIDL在工具编译时自动生成的)对象,这个对象封装了 IBinder 类型的 AMS 的引用。通过一系列进程间通信,最终调用 AMS 的 startActivity 方法。
AMS 到 ApplicationThread 的调用过程 Launcher 请求进入AMS 后,接着是AMS 到 ApplicationThread 调用流程,时序图如下所示:
在AMS 的startActivity 会使用 startActivityAsUser 实现功能,并获取UserHandle.getCallingUserld() 即 调用者的UserId 作为参数传入。之后,startActivityAsUser 中会判断调用者进程是否被隔离,如果隔离则抛出SecurityException 异常;接着,根据UserId 等参数检查调用者权限,如果没权限也抛出 SecurityException 异常。
AMS 中最终调用ActivityStater 的 startActivityLocked 方法,并且如果有 TaskRecord(代表启动的Activity所在的栈),则将其也作为参数传入;startActivityLocked 中会收集所有逻辑来决定如何将Intent 和Flags 转换为Activity(生成用于描述Activity 的  ActivityRecord 对象),并且将Activity 与Task 及 Stack 关联。
TaskRecord 用于描述一个 Activity 任务栈,Activity 任务栈其实是一个假想模型,并不真实存在。
 
最终调用到 ActivityStackSupervisor 的 startSpecificActivityLocked 方法时,会判断要启动的Activity 所在的应用程序进程是否已经运行,已经运行则调用 realStartActivityLocked 方法,并传入代表应用程序进程的 ProcessRecord。之后会调用 ApplicationThread 的 scheduleLaunchActivity 方法。当前代码逻辑运行在AMS所在进程(即SystemServer进程)中,通过 ApplicationThread 进程间通信,将程序执行到应用程序进程,ApplicationThread是AMS 进程与应用程序进程的通信桥梁 ,如下图所示:
ActivityThread 启动Activity 的过程 由前面的知识可知,目前的代码逻辑已经运行到应用程序进程中,先查看下ActivityThread 启动Activity 的时序图:
ApplicationThread 是 ActivityThread 的内部类,前面讲过应用程序进程创建完成后,会运行代表主线程的实例 ActivityThread 。接着上一节的内容查看 ApplicationThread.scheduleLaunchActivity 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 public  final  void  scheduleLaunchActivity (xxx,xx,xxx)      updateProcessState(procState ,false );     ActivityClientRecord r = new  ActivityClientRecord();     r.token = token;     r.ident =ident;     r.intent = intent;     r.referrer = referrer;     ...     updatePendingCoηfiguration (curConfig);     sendMessage(H.LAUNCH_ACTIVITY ,r); } 
在把启动Activity 必要的数据封装成 ActivityClientRecord 后,通过 sendMessage 方法将封装的数据以 H.LAUNCH_ACTIVITY 类型发送了出去,这里可以大胆地猜测sendMessage方法是通过handler的 sendMessage 执行的,果不其然,sendMessage 有多个重载方法,最终调用到如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 private  void  sendMessage (int  what ,Object obj ,int  argl ,int  arg2 ,boolean  async)     Message msg = Message obta  ()  ;     msg.what = what;     msg.ob]= obj;     msg.argl = argl;     msg.arg2 = arg2;     if  (async) {         msg .setAsynchronous(true );     }     mH.sendMessage(msg); 
这里的mH指的是 ActivityThread 的内部类 H,前面讲过,这个H是集成Handler,是应用进程中主线程的消息管理类,因为ApplicationThread 是一个Binder,它的调用逻辑都运行在Binder 线程池中,所以这里需要使用H将代码的逻辑切换到主线程中。 这样一来,我们只需要看 H 的handleMessage 方法即可知道具体的执行操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 private  class  H  extends  Handler      ...     public  void  handleMessage  (Message msg )       switch  (msg.what) {         case  LAUNCH_ACTIVITY:         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"activityStart" );         final  ActivityClientRecord r = (ActivityClientRecord) msg.obj;         r.packageinfo = getPackageinfoNoCheck(r.activityinfo.applicationinfo, r.compatlnfo);          handleLaunchActivity(r,null  ,"LAUNCH ACTIVITY" );          Trace.traceEnd (Trace . TRACE TAG ACTIVITY MANAGER);         break ;         ...     } 
在注释1处将传过来的 msg 的成员变量 obj 还原成 ActivityClientRecord,注释2获得LoadApk 类型的对象。应用程序进程要启动Activity时需要将该Activity 所属的APK 加载进来,而LoadApk 就是用来描述已经加载的APK 文件的。 注释3处调用 handleLaunchActivity 方法,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private  void  handleLaunchActivity (ActivityClientRecord r ,Intent customintent, String reason)      ...     WindowManagerGlobal.initialize ();          Activity a = performLaunchActivity(r, customintent);     if (a != null ){         ...                  handleResumeActivity(r.token, false , r.isForward,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);     }else {         ...                  ActivityManager getServ ce  ()  .finishActivity (r . token , Activity . RESULT CANCELED , null  , Activity . DONT_FINISH_TASK_WITH_ACTIVITY)   ;     } } 
注释1处performLaunchActivity 方法启动了 Activity,注释2处将Activity的状态设置为 Resume ,如果该Activity 为null,则会通知AMS 停止启动Activity。我们来看看 performLaunchActivity 方法做了什么:
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  Activity performLaunchActivity (ActivityClientRecord r , Intent customintent)           Activityinfo ainfo = r.activityinfo;     if  (r.packageinfo == null ) {                  r.packageinfo = getPackageinfo(ainfo.applicationinfo ,r.compatinfo,Context.CONTEXT_INCLUDE_CODE);     }     ComponentName component= r.intent.getComponent();     ...          Contextlmpl appContext = createBaseContextForActivity(r) ;      Activity activity = null ;     try  {         java.lang .ClassLoader cl= appContext.getClassLoader();                  activity = mInstrumentation newActivity (cl ,component.getClassName()  ,r.intent)  ;         ...     } catch  (Exception e) {         ...     }          try  {                  Application app = r.packageinfo.makeApplication(false  ,minstrumentation);          ...         if  (activity != null ) {                          activity.attach(....) ;             ...             if  (r.isPersistable()) {                 minstrumentation.callActivityOnCreate(activity,r.state ,r.persistentState);              } else  {                  minstrumentat on callActivityOnCreate (activ ty r .state)   ;             }             ...         }         r.paused = true  ;         mActivities.put(r.token,r);     } catch  (SuperNotCalledException e) {         throw  e ;     }catch  (Exception e) {         ...     }     return  activity; 
注释1处获取 Activityinfo,用于存储AndroidManifest 以及 代码中设置的Activity 和 Receiver 节点的信息,比如Activity 的theme 和launchMode 。注释3中获取要启动的Activity 的 ComponentName 对象,该对象中保存了该Activity 的包名和类名 。注释4中启动了Activity的上下文,注释5根据 Activity 的类名,用类加载器创建该 Activity 的实例。之后,注释6中创建了Application ,并且会调用 Application 的 onCreate方法。注释7中调用 Activity 的attach 方法初始化Activity,并且创建Window 对象(PhoneWindow)与Activity 自身关联。注释8中正式启动Activity,并调用Activity 的onCreate 方法。
至此,根Activity 就启动了,即应用程序启动了。
根Activity 启动过程中涉及的进程 根Activity 启动过程中涉及的4个进程之间关系如下:
首先Launcher 进程向 AMS 请求创建根 Activity ,AMS 会判断根Activity 所需要的应用程序进程是否存在,不存在就请求 Zygote 进程创建应用程序进程;之后,AMS 请求创建根Activity。上图中步骤 2 采用Socket 通信,步骤 1 和4采用Binder 通信。
读完书本,虽然各个点清晰,但是未能完整总结,以下 桌面点击图标 启动流程总结参考自他人博客  
点击桌面图标,Launcher 采用Binder IPC 方式向system_server 发起startActivity 请求。     
system_server 进程接收到请求后,向 zygote 进程发送创建进程请求。     
zygote 进程fork 出新进程,即App进程。     
App 进程通过 Binder IPC 向 system_server 发起 attachApplication 请求。      
system_server收到请求做一系列准备后,通过 Binder IPC 向App 进程发送 scheduleLauncherActivity请求。     
App 进程的Binder 线程(ApplicationThread)收到请求后,通过Handler 向主线程发送 LAUNCH_ACTIVITY 消息。     
主线程收到Message 后,通过反射机制创建目标Activity ,并回调Activity.onCreate 等方法。     
至此,App启动,开始Activity 生命周期。 
 
这个过程示意图如下所示:
Service 启动过程 Service 的启动过程和根Activity 的启动过程有部分相似知识点。Service 的启动过程可以分为两个部分讲解:分别是ContextImpl 到ActivityManageService 的调用过程,以及 ActivityThread 启动 Service。
ContextImpl 到 AMS 的调用过程 首先上时序图:
调用startService方法启动service,这个方法在 ContextWrapper 中实现