android 冷启动,android开启app过程( 三 )


newTask = true;
// 重用或者新建task
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
}else if (mSourceRecord != null) {
// 不是新建task的,重用原activity的task
result = setTaskFromSourceRecord();
}
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask...);
if (mDoResume) {
// 将任务栈移至前台
mTargetStack.moveToFront("startActivityUnchecked");
// 开始resume
mSupervisor.resumeFocusedStackTopActivityLocked(...)
}
}
总体来说,这个阶段就是根据activty的启动模式找到合适的task来放置activity,如果找不到或者强制新建 , 就会新建一个 。具体过程如下:
首先,根据launchMode和Intent中的FLAG_ACTIVITY_NEW_TASK等flag综合计算activity的启动模式 , 结果保存在mLaunchFlags中 。计算的过程不仅要考虑目标activity的launchMode , 也要考虑原来activity的launchMode和Intent中所带着的flag 。例如原来activity的launchMode是LAUNCH_SINGLE_INSTANCE,那么新activity只能新建task 。
调用getReusableIntentActivity()查找是否有可以重用的activity,这个只对LAUNCH_SINGLE_INSTANCE和LAUNCH_SINGLE_TASK或者FLAG_ACTIVITY_NEW_ TASK不为0有用的actvity,对于standard的activity , 该方法永远返回null 。查找的依据包括ActivityType、ComponentName和taskAffinity等 。
如果成功找到了可以重用的activity,要进行清理工作,把原来activity的信息替换成现在activity的信息 。例如同一个activity,两次启动的caller可能不同 , 要进行更新 。同时,还要进行根据launchMode来进行task内的清理 。例如LAUNCH_SINGLE_TASK的activity,如果此类所在的task上面有其它Activity,那么其它的Activity会被销毁 。
找到了可以重用的activity,那么就相当于把原来的activty替换成现在的activty,也就不用新建task了 。但是如果没有找到重用的activity , 那么调用setTaskFromReuseOrCreateNewTask()尝试寻找可以重用的task,注意此时前提是mStartActivity.resultTo == null && mLaunchFlags & FLAG_ACTIVITY_NEW_TASK,即 , 如果我们调用startActivityForResult启动的activity,那么是不能新建task的,二者是不兼容的 。没有找到重用的task,此时会新建一个TaskRecord , 置于前台,然后把activityt也置于task中activity队列的最后(即前台) 。如果是重用原activity的task , 那么执行setTaskFromSourceRecord,首先也是把该task移到前台,然后把activity置于该task的activity队列的最后 。
经过前面四步,actvity及其对应的task位置已经安排妥当,现在可以准备让这个activity开始工作了!那么这开工的第一步就是mTargetStack.startActivityLocked,这里面的工作主要是通知WindowManagerService(以后简称为WMS)准备activty的过渡动画和startingWindow 。
至此 , 为activity分配task的工作已经完毕 。
6、Pause前台activity
上面说到了为activity分配了任务栈之后,会调用resumeFocusedStackTopActivityLocked准备进行其resume 。调用流程如下:
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(targetStack,target...)
ActivityStack.resumeTopActivityUncheckedLocked(...)
ActivityStack.resumeTopActivityInnerLocked(...)
// next是要resume的activity
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
next.launching = true; // 将activity的状态置为launching
// pause所有的任务栈
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
// pause当前栈的activity
if (mResumedActivity != null && mResumedActivity != next) {
pausing |= startPausingLocked(userLeaving, false, next, false);
}
if (pausing && !resumeWhilePausing) {