基于Android 6.0的源码剖析, 分析android Activity启动流程,相关源码:
<code>startActivity</code>的整体流程与startService启动过程分析非常相近,但比Service启动更为复杂,多了stack/task以及UI的相关内容以及Activity的生命周期更为丰富。
Activity启动发起后,通过Binder最终交由system进程中的AMS来完成,则启动流程如下图:

接下来,从源码来说说每个过程。
[-> Activity.java]
execStartActivity()方法的参数:
<code>mAppThread</code>: 数据类型为ApplicationThread,通过mMainThread.getApplicationThread()方法获取。
<code>mToken</code>: 数据类型为IBinder.
[-> Instrumentation.java]
关于 ActivityManagerNative.getDefault()返回的是ActivityManagerProxy对象. 此处startActivity()的共有10个参数, 下面说说每个参数传递AMP.startActivity()每一项的对应值:
caller: 当前应用的ApplicationThread对象mAppThread;
callingPackage: 调用当前ContextImpl.getBasePackageName(),获取当前Activity所在包名;
intent: 这便是启动Activity时,传递过来的参数;
resolvedType: 调用intent.resolveTypeIfNeeded而获取;
resultTo: 来自于当前Activity.mToken
resultWho: 来自于当前Activity.mEmbeddedID
requestCode = -1;
startFlags = 0;
profilerInfo = null;
options = null;
[-> ActivityManagerNative.java :: ActivityManagerProxy]
AMP经过binder IPC,进入ActivityManagerNative(简称AMN)。接下来程序进入了system_servr进程,开始继续执行。
[-> ActivityManagerNative.java]
[-> ActivityManagerService.java]
此处mStackSupervisor的数据类型为<code>ActivityStackSupervisor</code>
当程序运行到这里时, ASS.startActivityMayWait的各个参数取值如下:
caller = ApplicationThreadProxy, 用于跟调用者进程ApplicationThread进行通信的binder代理类.
callingUid = -1;
callingPackage = ContextImpl.getBasePackageName(),获取调用者Activity所在包名
intent: 这是启动Activity时传递过来的参数;
resolvedType = intent.resolveTypeIfNeeded
voiceSession = null;
voiceInteractor = null;
resultTo = Activity.mToken, 其中Activity是指调用者所在Activity, mToken对象保存自己所处的ActivityRecord信息
resultWho = Activity.mEmbeddedID, 其中Activity是指调用者所在Activity
outResult = null;
config = null;
ignoreTargetSecurity = false;
userId = AMS.handleIncomingUser, 当调用者userId跟当前处于同一个userId,则直接返回该userId;当不相等时则根据调用者userId来决定是否需要将callingUserId转换为mCurrentUserId.
iContainer = null;
inTask = null;
再来看看这个方法的源码:
[-> ActivityStackSupervisor.java]
该过程主要功能:通过resolveActivity来获取ActivityInfo信息, 然后再进入ASS.startActivityLocked().先来看看
ActivityManager类有如下4个flags用于调试:
START_FLAG_DEBUG:用于调试debug app
START_FLAG_OPENGL_TRACES:用于调试OpenGL tracing
START_FLAG_NATIVE_DEBUGGING:用于调试native
START_FLAG_TRACK_ALLOCATION: 用于调试allocation tracking
AppGlobals.getPackageManager()经过函数层层调用,获取的是ApplicationPackageManager对象。经过binder IPC调用,最终会调用PackageManagerService对象。故此时调用方法为PMS.resolveIntent().
[-> PackageManagerService.java]
ASS.resolveActivity()方法的核心功能是找到相应的Activity组件,并保存到intent对象。
其中有两个返回值代表启动Activity失败:
START_INTENT_NOT_RESOLVED: 从Intent中无法找到相应的Component或者ActivityInfo
START_NOT_CURRENT_USER_ACTIVITY:该Activity对当前用户不可见
当mAppSwitchesAllowedTime时间小于当前时长,或者具有STOP_APP_SWITCHES的权限,则允许app发生切换操作.
其中mAppSwitchesAllowedTime, 在<code>AMS.stopAppSwitches()</code>的过程中会设置为:<code>mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME</code>. 禁止app切换的timeout时长为5s(APP_SWITCH_DELAY_TIME = 5s).
当发送5秒超时或者执行<code>AMS.resumeAppSwitches()</code>过程会将mAppSwitchesAllowedTime设置0, 都会开启允许app执行切换的操作.另外,禁止App切换的操作,对于同一个app是不受影响的,有兴趣可以进一步查看<code>checkComponentPermission</code>过程.
<code>mPendingActivityLaunches</code>记录着所有将要启动的Activity, 是由于在<code>startActivityLocked</code>的过程时App切换功能被禁止, 也就是不运行切换Activity, 那么此时便会把相应的Activity加入到<code>mPendingActivityLaunches</code>队列. 该队列的成员在执行完<code>doPendingActivityLaunchesLocked</code>便会清空.
启动mPendingActivityLaunches中所有的Activity, 由于doResume = false, 那么这些activtity并不会进入resume状态,而是设置delayedResume = true, 会延迟resume.