ActivityStarter封装了一个activity启动的过程(包括上下文环境),不采用情景栈分析法真的很难分析,这里采用情景分析法把该函数分析. 整体代码如下:
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
//1. 初始化环境和lunchModeFlags
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
computeLaunchingTaskFlags();
computeSourceStack();
mIntent.setFlags(mLaunchFlags);
//2. 复用activity逻辑
mReusedActivity = getReusableIntentActivity();
......
if (mReusedActivity != null) {
......
mReusedActivity = setTargetStackAndMoveToFrontIfNeeded(mReusedActivity);
......
setTaskFromIntentActivity(mReusedActivity);
if (!mAddingToTask && mReuseTask == null) {
resumeTargetStackIfNeeded();
return START_TASK_TO_FRONT;
}
}
.......
//singleTop 或者singleInstance的处理
if (dontStart) {
ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
// For paranoia, make sure we have correctly resumed the top activity.
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
......
top.deliverNewIntentLocked(
mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
......
return START_DELIVERED_TO_TOP;
}
//3. 设置对应task并带到前台
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
setTaskFromReuseOrCreateNewTask(taskToAffiliate);
......
} else if (mSourceRecord != null) {
......
final int result = setTaskFromSourceRecord();
......
} else if (mInTask != null) {
......
final int result = setTaskFromInTask();
if (result != START_SUCCESS) {
return result;
}
} else {
setTaskToCurrentTopOrCreateNewTask();
}
// 4. 启动Activity
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
// 5. 使Activity可见
if (mDoResume) {
if (!mLaunchTaskBehind) {
mService.setFocusedActivityLocked(mStartActivity, "startedActivity");
}
final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
.... . .
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mWindowManager.executeAppTransition();
} else {
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
......
return START_SUCCESS;
}
我们先整体介绍下这里activity启动的过程
下面就围绕这4步对代码进行展开说明
一.对启动参数进行初始化,主要是下面三个函数
private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
boolean doResume, int startFlags, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
setInitialState 函数比较简单,主要初始化了如下变量
private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
boolean launchSingleTask, int launchFlags) {
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
(launchSingleInstance || launchSingleTask)) {
launchFlags &=
~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
} else {
switch (r.info.documentLaunchMode) {
case ActivityInfo.DOCUMENT_LAUNCH_NONE:
break;
case ActivityInfo.DOCUMENT_LAUNCH_INTO_EXISTING:
launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
break;
case ActivityInfo.DOCUMENT_LAUNCH_ALWAYS:
launchFlags |= Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
break;
case ActivityInfo.DOCUMENT_LAUNCH_NEVER:
launchFlags &= ~FLAG_ACTIVITY_MULTIPLE_TASK;
break;
}
}
return launchFlags;
}
可以看到launchSingleInstance和launchSingleTask模式的activity是不支持FLAG_ACTIVITY_NEW_DOCUMENT标志的,不允许.所以直接干掉这个表示,使之失效.
另外对于指定了 documentLaunchMode的activity
- DOCUMENT_LAUNCH_NONE不用任何操作.
- DOCUMENT_LAUNCH_INTO_EXISTING或者DOCUMENT_LAUNCH_ALWAYS 代表activity自动带有FLAG_ACTIVITY_NEW_DOCUMENT标志
- DOCUMENT_LAUNCH_NEVER 则会把FLAG_ACTIVITY_MULTIPLE_TASK标志去掉,表示activity永远不主动在新的task中创建
所以这里我们可以知道对于document模式,都会转化为FLAG_ACTIVITY_MULTIPLE_TASK和FLAG_ACTIVITY_NEW_DOCUMENT标志进行处理
mLaunchTaskBehind = r.mLaunchTaskBehind
&& !mLaunchSingleTask && !mLaunchSingleInstance
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
代码是这么写的,其实判断mLaunchSingleTask && !mLaunchSingleInstance是没有必要的,因为在前面adjustLaunchFlagsToDocumentMode里面已经处理了.
2 private void computeLaunchingTaskFlags() 计算mLaunchFlags,这里进一步计算关于task的启动参数.
rivate void computeLaunchingTaskFlags() {
if (mSourceRecord == null && mInTask != null && mInTask.getStack() != null) {
//1 对于mInTask的处理
final Intent baseIntent = mInTask.getBaseIntent();
final ActivityRecord root = mInTask.getRootActivity();
if (baseIntent == null) {
ActivityOptions.abort(mOptions);
throw new IllegalArgumentException("Launching into task without base intent: "
+ mInTask);
}
if (mLaunchSingleInstance || mLaunchSingleTask) { //对于这两种类型的activity要想在新的task中创建(新的rootActivity)必须task 中不包含才能创建新的
......
}
if (root == null) { //注意mInTask默认的语义就是把要启动的activity作为task的rootActivity
final int flagsOfInterest = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK
| FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_RETAIN_IN_RECENTS;
mLaunchFlags = (mLaunchFlags & ~flagsOfInterest)
| (baseIntent.getFlags() & flagsOfInterest);
mIntent.setFlags(mLaunchFlags);
mInTask.setIntent(mStartActivity);
mAddingToTask = true;
} else if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
mAddingToTask = false;
} else {
mAddingToTask = true;
}
mReuseTask = mInTask;
} else {
// 2 sourceRecord的处理
mInTask = null;
if ((mStartActivity.isResolverActivity() || mStartActivity.noDisplay) && mSourceRecord != null && mSourceRecord.isFreeform()) {
mAddingToTask = true;
}
}
//3 最后针对需要添加FLAG_ACTIVITY_NEW_TASK的情况处理
if (mInTask == null) {
if (mSourceRecord == null) {
if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
}
} else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
} else if (mLaunchSingleInstance || mLaunchSingleTask) {
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
}
}
}
代码也是分为三个部分处理. 1,2 是两种条件的处理,3是总的处理.
首先对于条件1进行说明,mSourceRecord == null && mInTask != null && mInTask.getStack() != null 这个条件主要是用于处理mInTask, 第一个条件mSourceRecord == null说明使用SourceRecord确定task的优先级要高于参数中指定的mInTask. 如果SourceRecord的task好指定的mInTask都存在,则以mSourceRecord的为准.
3 private void computeSourceStack() 函数用于计算sourceStack, 就是调用者所在的stack
private void computeSourceStack() {
if (mSourceRecord == null) {
mSourceStack = null;
return;
}
if (!mSourceRecord.finishing) {
mSourceStack = mSourceRecord.getStack();
return;
}
if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0) {
mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
mNewTaskInfo = mSourceRecord.info;
final TaskRecord sourceTask = mSourceRecord.getTask();
mNewTaskIntent = sourceTask != null ? sourceTask.intent : null;
}
mSourceRecord = null;
mSourceStack = null;
}
代码很简单,首先如果不存在mSourceRecord那么mSourceStack也是不存在的
如果mSourceRecord所代表的activity没有被关闭则直接使用sourceRecord所代表的Activity作为sourceStack
最后的情况则代表mSouorceRecord所代表的activity已经执行的finish方法,那么好了,我们要强行添加FLAG_ACTIVITY_NEW_TASK标志使activity启动到一个新的task中. 并且将原来sourceRecord的信息保存下来主要就是原来的taskinfo信息和intent信息, 最后设置mSourceRecord = null;
mSourceStack = null;保存task的intent信息和taskinfo信息是为了新建task的时候尝试恢复这个task
二 复用activity的情况
1 getReusableIntentActivity()函数,函数的名字很不友好,看似是获取复用的activity实则是获取复用的task
private ActivityRecord getReusableIntentActivity() {
boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
(mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
|| mLaunchSingleInstance || mLaunchSingleTask;
putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;
ActivityRecord intentActivity = null;
if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId());
intentActivity = task != null ? task.getTopActivity() : null;
} else if (putIntoExistingTask) {
if (mLaunchSingleInstance) {
intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info, false);
} else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
!mLaunchSingleTask);
} else {
intentActivity = mSupervisor.findTaskLocked(mStartActivity, mSourceDisplayId);
}
}
return intentActivity;
}
这里罗列了一些可以复用task的情况,主要包括设置了FLAG_ACTIVITY_NEW_TASK标志并且没有设置FLAG_ACTIVITY_MULTIPLE_TASK的情况,如果设置了FLAG_ACTIVITY_MULTIPLE_TASK标志需要另外起一个task盛放要启动的activity. 以及lunchMode为singleTask或者singleInstance的情况和明确在AppOptions中指定的使用的task的情况。 对于明确指定的情况肯定要复用task,前两种情况呢,还要在不使用inTask的情况和mStartActivity.resultTo不为空的情况。 指定了InTask参数和mStartActivity.resultTo不为空的情况都会单独处理。
还要说明的是对于singleInstance的情况要找到task中包含要启动activity的task进行复用,寻找到过程使用mSupervisor.findActivityLocked(mIntent, mStartActivity.info, false)函数,其中第三个参数为false表示不需要匹配intent,因为lunchMode为singleInstance的时候,它所在的task只能放一个activity. 如果存在这样的task那就必然使我们要找的task了。对于指定了FLAG_ACTIVITY_LAUNCH_ADJACENT的情况也是要找到与启动activity相同的task。 最后如果并非是singleInstance或者FLAG_ACTIVITY_LAUNCH_ADJACENT方式启动activity,意味着使用mSupervisor.findTaskLocked(mStartActivity, mSourceDisplayId),这种情况只是找到合适的task,并不要求task中包含对应的activity。
- 获取到可复用的task和这个task上的activity(或许是与我们要启动的activity相同compoentname的activity或是可复用task栈顶的activity) ,整体流程如下
if (reusedActivity != null) {
......
if (mStartActivity.getTask() == null) {
mStartActivity.setTask(reusedActivity.getTask());
}
if (reusedActivity.getTask().intent == null) {
reusedActivity.getTask().setIntent(mStartActivity);
}
//清除task中复用的activity上面的activity
if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| isDocumentLaunchesIntoExisting(mLaunchFlags)
|| mLaunchSingleInstance || mLaunchSingleTask) {
final TaskRecord task = reusedActivity.getTask();
final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
mLaunchFlags);
if (reusedActivity.getTask() == null) {
reusedActivity.setTask(task);
}
if (top != null) {
if (top.frontOfTask) {
top.getTask().setIntent(mStartActivity);
}
//执行newIntent
ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.getTask());
top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
mStartActivity.launchedFromPackage);
}
}
sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
//将复用的task拿到前台
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
final ActivityRecord outResult =
outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
outActivity[0] = reusedActivity;
}
//把task拿到前台就可以了不需要重启
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
resumeTargetStackIfNeeded();
return START_RETURN_INTENT_TO_CALLER;
}
//根据复用情况设置task
setTaskFromIntentActivity(reusedActivity);
if (!mAddingToTask && mReuseTask == null) {
resumeTargetStackIfNeeded();
if (outActivity != null && outActivity.length > 0) {
outActivity[0] = reusedActivity;
}
return START_TASK_TO_FRONT;
}
}
这段代码还是比较不容易弄懂的,注意我们这里的mStartActivity和reusedActivity的含义,mStartActivity才是我们要启动的activity.,而reusedActivity只不过是我们要复用的task上的一个activity,有可能是我们要复用的activity,也可能只是这个task最上面的activity.
这段代码首先如果要启动的activity还没有设置task,就设置成复用的task,另外如果复用的task还没有mStartActivity则根据activity设置baseintent.
后面一段清除task中复用的activity上面的activity的逻辑,主要是对于FLAG_ACTIVITY_CLEAR_TOP(含义就是清除与mStartActivity相同的activity上面的activity). 另外对于isDocumentLaunchesIntoExisting(mLaunchFlags)
|| mLaunchSingleInstance || mLaunchSingleTask 这三种模式的也需要清除StartActivity相同的activity上面的activity。函数体使用 final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
mLaunchFlags);函数进行task的清除,值得注意的一点是performClearTaskLocked(ActivityRecord newR, int launchFlags)函数内部如果和mStartActivity相同compoentname的activity的启动模式是默认的ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE,则也会将这个activity销毁。对于SingleInstance || SingleTask|| singleTop启动模式的则不会被销毁。所以task.performClearTaskForReuseLocked(mStartActivity,
mLaunchFlags)返回后对于要启动的activity的启动模式为LAUNCH_MULTIPLE的,返回值top肯定是空的。所以不会发送newIntent的请求给客户端。
后面setTargetStackAndMoveToFrontIfNeeded(reusedActivity)函数是把复用的task所在的stack设置为fourceStack并且把复用的task拿到栈顶。 请参考https://blog.csdn.net/woai110120130/article/details/79720840
执行完setTargetStackAndMoveToFrontIfNeeded函数后就可以设置返回结果了,为什么这里就可以设置了呢,注意判断条件
后面对startFlags参数的START_FLAG_ONLY_IF_NEEDED标志处理,这种情况不需要去真的启动activity,只需要使task放到前台就可以了,这种情况多是从桌面点击图标恢复task的情况。
后面 setTaskFromIntentActivity(reusedActivity)也是比较关键的函数,我在代码上进行注释,具体细节就不在讲解,最后对于复用的情况,到这里就处理完了,只是把task带到了前台,所以返回START_TASK_TO_FRONT。
private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
if ((mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) { //条件1 清空task
final TaskRecord task = intentActivity.getTask();
task.performClearTaskLocked();
mReuseTask = task;
mReuseTask.setIntent(mStartActivity);
mMovedOtherTask = true;
} else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| mLaunchSingleInstance || mLaunchSingleTask) { //2 clear top
ActivityRecord top = intentActivity.getTask().performClearTaskLocked(mStartActivity,
mLaunchFlags);
if (top == null) {
mAddingToTask = true;
mStartActivity.setTask(null);
mSourceRecord = intentActivity;
final TaskRecord task = mSourceRecord.getTask();
if (task != null && task.getStack() == null) {
mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
null /* bounds */, mLaunchFlags, mOptions);
mTargetStack.addTask(task,
!mLaunchTaskBehind /* toTop */, "startActivityUnchecked");
}
}
} else if (mStartActivity.realActivity.equals(intentActivity.getTask().realActivity)) {
//3 singleTop
if (((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop)
&& intentActivity.realActivity.equals(mStartActivity.realActivity)) {
ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity,
intentActivity.getTask());
if (intentActivity.frontOfTask) {
intentActivity.getTask().setIntent(mStartActivity);
}
intentActivity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
mStartActivity.launchedFromPackage);
} else if (!intentActivity.getTask().isSameIntentFilter(mStartActivity)) {
mAddingToTask = true;
mSourceRecord = intentActivity;
}
} else if ((mLaunchFlags & FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { //4 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
mAddingToTask = true;
mSourceRecord = intentActivity;
} else if (!intentActivity.getTask().rootWasReset) { //5 rootWasReset
intentActivity.getTask().setIntent(mStartActivity);
}
}
setTaskFromIntentActivity 从函数的名字来看是根据intentActivity设置task, 参数是ActivityStarter->startActivityUnchecked()中的reusedActivity,函数主要分为五中情况处理
5 所说的情况是希望把要启动的activity放到task的最底部,但是现在的代码结构做不到,只是把task更新为mStartActivity为baseIntent
到这里setTaskFromIntentActivity分析完了,我们来总结下这里设置的几个变量
mReuseTask 复用task, 这里有两种情况会设置,第一种是inUseTask可用的时候,第二种情况是FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK情况
mMovedOtherTask 表示task已经被移动到顶端,不需要更新task的returnType
mAddingToTask 表示要新创建activity,不能复用
回到二(Activity复用的情况下,只剩下一段代码)如下
if (!mAddingToTask && mReuseTask == null) {
resumeTargetStackIfNeeded();
if (outActivity != null && outActivity.length > 0) {
outActivity[0] = reusedActivity;
}
return START_TASK_TO_FRONT;
}
这里mAddingToTask为假表示可以复用activity,mReuseTask不为空说明task被清除了,所以这两个条件满足可以复用activity并且task没有被清空就可以设置栈顶activity可见并返回START_TASK_TO_FRONT,到这里activity的复用逻辑就快要执行完成了
跳出reusedActivity不为空的情况,因为获取resuedActivity的时候并没有处理所有情况,如mInTask == null 或者mStartActivity.resultTo == null的情况,这里检查topActivity是否为我们要启动的activity. 代码如下
final ActivityStack topStack = mSupervisor.mFocusedStack;
final ActivityRecord topFocused = topStack.topActivity();
final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop || mLaunchSingleTask);
if (dontStart) {
ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.getTask());
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do
// anything if that is the case, so this is it!
return START_RETURN_INTENT_TO_CALLER;
}
top.deliverNewIntentLocked(
mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
// Don't use mStartActivity.task to show the toast. We're not starting a new activity
// but reusing 'top'. Fields in mStartActivity may not be fully initialized.
mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredLaunchStackId,
preferredLaunchDisplayId, topStack.mStackId);
return START_DELIVERED_TO_TOP;
}
主要就是对FLAG_ACTIVITY_SINGLE_TOP和singleTask,singleTop, singleTask的处理,代码很简单就不解释了。
到这里activity的复用逻辑就介绍完了
三 第三部分的操作主要就是task的创建或者复用,并且拿到前台。
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { //1创建新的或者重用mReuseTask
newTask = true;
String packageName= mService.mContext.getPackageName();
if (mPerf != null) {
mStartActivity.perfActivityBoostHandler =
mPerf.perfHint(BoostFramework.VENDOR_HINT_FIRST_LAUNCH_BOOST, packageName, -1, BoostFramework.Launch.BOOST_V1);
}
result = setTaskFromReuseOrCreateNewTask(
taskToAffiliate, preferredLaunchStackId, topStack);
} else if (mSourceRecord != null) { //2 从mSourceRecord获取task
result = setTaskFromSourceRecord();
} else if (mInTask != null) { //3 使用mInTask
result = setTaskFromInTask();
} else { //4 其他情况
// This not being started from an existing activity, and not part of a new task...
// just put it in the top task, though these days this case should never happen.
setTaskToCurrentTopOrCreateNewTask();
}
代码也是分为四中情况 ,代码注释中写的很清楚,函数的名字也比较清晰,就不分析了,我们在分析stack管理的时候再进行分析。
四. 最后这段代码主要的逻辑就是activity的情动和显示的逻辑,也很简单
mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
if (mSourceRecord != null) {
mStartActivity.getTask().setTaskToReturnTo(mSourceRecord);
}
if (newTask) {
EventLog.writeEvent(
EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
mStartActivity.getTask().taskId);
}
ActivityStack.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
mTargetStack.mLastPausedActivity = null;
sendPowerHintForLaunchStartIfNeeded(false /* forceSend */);
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mWindowManager.executeAppTransition();
} else {
// If the target stack was not previously focusable (previous top running activity
// on that stack was not visible) then any prior calls to move the stack to the
// will not update the focused stack. If starting the new activity now allows the
// task stack to be focusable, then ensure that we now update the focused stack
// accordingly.
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else {
mTargetStack.addRecentActivityLocked(mStartActivity);
}
mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
preferredLaunchDisplayId, mTargetStack.mStackId);
return START_SUCCESS;
也没有什么好解释的,具体启动和显示的过程我们单独写一片文章分析