分析了栈的管家和栈.有些摸不到头脑,我们顺着一个情景来分析.本文重点关注启动过程actvity的生命周期和调用对于task和stack的管理.
对于怎么去选择task和stack我们在分析activity启动的文章中已经分析了,这里直接从对生命周期处理来分析
首先这种情况选择task是在setTaskFromSourceRecord函数中
private int setTaskFromSourceRecord() {
final TaskRecord sourceTask = mSourceRecord.task;
......
if (mTargetStack == null) {
mTargetStack = sourceTask.stack;
}
.....
if (mDoResume) {
//1 移动stack到前面
mTargetStack.moveToFront("sourceStackToFront");
}
final TaskRecord topTask = mTargetStack.topTask();
if (topTask != sourceTask && !mAvoidMoveToFront) {
//2 移动task到stack前面
mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions,
mStartActivity.appTimeTracker, "sourceTaskToFront");
}
......
// An existing activity is starting this new activity, so we want to keep the new one in
// the same task as the one that is starting it.
//3 设置activity的task
mStartActivity.setTask(sourceTask, null);
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ " in existing task " + mStartActivity.task + " from source " + mSourceRecord);
return START_SUCCESS;
}
1首先调用ActivityStack的moveToFront函数把stack移动到上边来
void moveToFront(String reason, TaskRecord task) {
if (!isAttached()) {
return;
}
mStacks.remove(this);
int addIndex = mStacks.size();
if (addIndex > 0) {
final ActivityStack topStack = mStacks.get(addIndex - 1);
if (StackId.isAlwaysOnTop(topStack.mStackId) && topStack != this) {
// If the top stack is always on top, we move this stack just below it.
addIndex--;
}
}
mStacks.add(addIndex, this);
// TODO(multi-display): Needs to also work if focus is moving to the non-home display.
if (isOnHomeDisplay()) {
mStackSupervisor.setFocusStackUnchecked(reason, this);
}
if (task != null) {
insertTaskAtTop(task, null);
} else {
task = topTask();
}
if (task != null) {
mWindowManager.moveTaskToTop(task.taskId);
}
}
函数首先计算出stack的位置,然后放到对应的位置,如果是在home display上则还要设置这个stack为焦点stack,之后把task插入到stack顶部,最后移动WMS中的task,者几个步骤在此情景都没有任何实质性的变化.
这里可以总结下过程
1 移动stack到前台,moveToFront函数
2 移动task到stack前边,对于window的移动 mWindowManager.moveTaskToTop(task.taskId)
3 移动activity到task上,请看startActivityLocked函数
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
ActivityOptions options) {
......
TaskRecord task = null;
if (!newTask) {
// If starting in an existing task, find where that is...
boolean startIt = true;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// All activities in task are finishing.
continue;
}
//2 如果这个task不可见,被全屏的task遮挡,直接插入到task中
if (task == r.task) {
if (!startIt) {
task.addActivityToTop(r);
r.putInHistory();
addConfigOverride(r, task);
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
ActivityOptions.abort(options);
return;
}
break;
} else if (task.numFullscreen > 0) {
startIt = false;
}
}
}
// Place a new activity at top of stack, so it is next to interact
// with the user.
// If we are not placing the new activity frontmost, we do not want
// to deliver the onUserLeaving callback to the actual frontmost
// activity
//3 task不在前台不需要执行Activity的onUserLeaving函数 设置mUserLeaving为false
if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
mStackSupervisor.mUserLeaving = false;
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"startActivity() behind front, mUserLeaving=false");
}
task = r.task;
// Slot the activity into the history stack and proceed
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
new RuntimeException("here").fillInStackTrace());
//3 添加activity到task中
task.addActivityToTop(r);
//4 更新task中activity的frontOfTask变量,为true代表该activity在task最前面
task.setFrontOfTask();
r.putInHistory();
//5 如果stack不是home stack中,或者activity数量大于0,这种情况要启动starting window
//因为home stack下面是wall paper不需要启动starting window,而activity为0表示没有要启动的activity
if (!isHomeStack() || numActivities() > 0) {
// We want to show the starting preview window if we are
// switching to a new task, or the next activity's process is
// not currently running.
//6 进程没有启动或者新的task要显示starting icon
boolean showStartingIcon = newTask;
ProcessRecord proc = r.app;
if (proc == null) {
proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);
}
if (proc == null || proc.thread == null) {
showStartingIcon = true;
}
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare open transition: starting " + r);
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
//7 不需要执行动画设置动画为NONE
mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
mNoAnimActivities.add(r);
} else {
mWindowManager.prepareAppTransition(newTask
? r.mLaunchTaskBehind
? TRANSIT_TASK_OPEN_BEHIND
: TRANSIT_TASK_OPEN
: TRANSIT_ACTIVITY_OPEN, keepCurTransition);
mNoAnimActivities.remove(r);
}
//8 添加AppToken到WMS中
addConfigOverride(r, task);
boolean doShow = true;
if (newTask) {
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
resetTaskIfNeededLocked(r, r);
doShow = topRunningNonDelayedActivityLocked(null) == r;
}
} else if (options != null && options.getAnimationType()
== ActivityOptions.ANIM_SCENE_TRANSITION) {
doShow = false;
}
if (r.mLaunchTaskBehind) {
//9 通知wms,activity可见的.虽然是在后台启动
mWindowManager.setAppVisibility(r.appToken, true);
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
} else if (SHOW_APP_STARTING_PREVIEW && doShow) {
//10 创建starting window
ActivityRecord prev = r.task.topRunningActivityWithStartingWindowLocked();
if (prev != null) {
// We don't want to reuse the previous starting preview if:
// (1) The current activity is in a different task.
if (prev.task != r.task) {
prev = null;
}
// (2) The current activity is already displayed.
else if (prev.nowVisible) {
prev = null;
}
}
//11 如果前面的activity不可见,但是有一个starting window,复用或者新创建一个starting window
r.showStartingWindow(prev, showStartingIcon);
}
} else {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
//12 创建AppWindowToken
addConfigOverride(r, task);
ActivityOptions.abort(options);
options = null;
}
if (VALIDATE_TOKENS) {
validateAppTokensLocked();
}
}
我们再在总结下这一步
1 添加activity到task,task.addActivityToTop(r);
2 创建动画
3 创建AppWindowToken到WMS,addConfigOverride(r, task);
4 创建starting window,r.showStartingWindow(prev, showStartingIcon)
下面一个步骤是调用 AMS的方法setFocusedActivityLocked(ActivityRecord r, String reason)
if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
mWindowManager.setFocusedApp(r.appToken, true);
}
主要是更新AMS的mFocusedActivity和更新WMS的mWindowManager.setFocusedApp(r.appToken, true)
设置完成焦点Activity后就执行
resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions); 去真正的activity.
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
}
return false;
}
前面我们已经把stack移动到前台,设置为focuse activity,所以这里就直接使用resumeTopActivityUncheckedLocked去resume activity
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
inResumeTopActivity变量防止嵌套执行,最终还是执行resumeTopActivityInnerLocked(prev, options)函数创建activity
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
//1 没有启动完成直接返回
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
}
//2 父activity不是RESUMED状态,子activity也不能resume
ActivityRecord parent = mActivityContainer.mParentActivity;
if ((parent != null && parent.state != ActivityState.RESUMED) ||
!mActivityContainer.isAttachedLocked()) {
// Do not resume this stack if its parent is not resumed.
// TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st.
return false;
}
//4 移除topActivity下面全屏activity下面的starting window
mStackSupervisor.cancelInitializingActivities();
// Find the first activity that is not finishing.
//5 这里为焦点stack,最上面的activity也是我们要启动的actvity
final ActivityRecord next = topRunningActivityLocked();
// Remember how we'll process this pause/resume situation, and ensure
// that the state is reset however we wind up proceeding.
//6 从锁存中拿到userLeaving变量,恢复锁存
final boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
//7 在我们这个情景中prev==next
final TaskRecord prevTask = prev != null ? prev.task : null;
......
next.delayedResume = false;
......
// The activity may be waiting for stop, but that is no longer
// appropriate for it.
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
// If we are currently pausing an activity, then don't do anything until that is done.
//8 这里全部activity没有pause完成返回false,完成后还会调用该函数
if (!mStackSupervisor.allPausedActivitiesComplete()) {
if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
"resumeTopActivityLocked: Skip resume: some activity pausing.");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
// We need to start pausing the current