一、主要涉及4個類
1) ActivityRecord
源碼注釋:An entry in the history stack, representing an activity.
翻譯一下:存在歷史棧的一個實例,代表一個Activity。
2) TaskRecord
Activity棧,內(nèi)部維護一個ArrayList<ActivityRecord>
3) ActivityStack
并不是一個Activity棧,真正意義上的Activity棧是TaskRecord,這個類是負責(zé)管理各個Activity棧,內(nèi)部維護一個ArrayList<TaskRecord>
4) ActivityStackSupervisor
內(nèi)部持有一個ActivityStack,而ActivityStack內(nèi)部也持有ActivityStackSupervisor,相當于ActivityStack的輔助管理類
ActivityRecord
final class ActivityRecord {
TaskRecord task; // the task this is in.
final IApplicationToken.Stub appToken;
final int userId;
int theme;
int launchMode;
...
}
成員變量task表示自己所在的TaskRecord,這樣要找到自己所在的TaskRecord就不必遍歷查找了。
TaskRecord
final class TaskRecord {
/** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities;
/** Current stack */
ActivityStack stack;
}
同樣的道理,成員變量stack表示自己所在的ActivityStack
ActivityStack
final class ActivityStack {
private ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
/** Run all ActivityStacks through this */
final ActivityStackSupervisor mStackSupervisor;
ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer, RecentTasks recentTasks) {
mStackSupervisor = activityContainer.getOuter();
...
}
}
ActivityStackSupervisor
public final class ActivityStackSupervisor {
private ActivityStack mFocusedStack;
}
二、場景解析
1、從桌面第一次啟動App
startActivityLocked里構(gòu)造一個ActivityRecord
新建一個TaskRecord,并存入mTaskHistory
ActivityRecord存入mActivities

final int startActivityUncheckedLocked(...) {
final int startActivityUncheckedLocked(...) {
if (reuseTask == null) {
r.setTask(targetStack.createTaskRecord(...);
...
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
...
}
}
- TaskRecord存入mTaskHistory
TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
boolean toTop) {
TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
voiceInteractor);
addTask(task, toTop, false);
return task;
}
void addTask(final TaskRecord task, final boolean toTop, boolean moving) {
task.stack = this;
if (toTop) {
insertTaskAtTop(task, null);
} else {
mTaskHistory.add(0, task);
updateTaskMovement(task, false);
}
...
}
private void insertTaskAtTop(TaskRecord task, ActivityRecord newActivity) {
...
mTaskHistory.add(taskNdx, task);
updateTaskMovement(task, true);
}
- ActivityRecord存入mActivities

final void startActivityLocked(ActivityRecord r, boolean newTask, ...) {
...
task = mTaskHistory.get(taskNdx);
...
task.addActivityToTop(r);
}
void addActivityToTop(ActivityRecord r) {
addActivityAtIndex(mActivities.size(), r);
}
void addActivityAtIndex(int index, ActivityRecord r) {
...
mActivities.add(index, r);
...
}
2、App啟動一個Activity
會不會新建一個TaskRecord取決于launchMode,默認的standard模式不會創(chuàng)建新的TaskRecord
構(gòu)造一個ActivityRecord存入mActivities,與上面第二步一樣
3、回退

/** @return true if this was the last activity in the task */
boolean removeActivity(ActivityRecord r) {
mActivities.remove(r);
...
if (mActivities.isEmpty()) {
return !mReuseTask;
}
...
return false;
}
4、再次回退,回到桌面
從mActivities移除當前ActivityRecord與上面一樣,只是當mActivities為空時,會觸發(fā)mTaskHistory移除當前TaskRecord,如果mTaskHistory為空,則切換到桌面,給mStackSupervisor.mFocusedStack重新賦值
private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
...
final TaskRecord task = r.task;
if (task != null && task.removeActivity(r)) {
if (mStackSupervisor.isFrontStack(this) && task == topTask() &&
task.isOverHomeStack()) {
mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason);
}
removeTask(task, reason);
}
}
void removeTask(TaskRecord task, String reason, boolean notMoving) {
...
mTaskHistory.remove(task);
...
if (mTaskHistory.isEmpty()) {
final boolean notHomeStack = !isHomeStack();
if (isOnHomeDisplay()) {
String myReason = reason + " leftTaskHistoryEmpty";
if (mFullscreen || !adjustFocusToNextVisibleStackLocked(null, myReason)) {
mStackSupervisor.moveHomeStack(notHomeStack, myReason);
}
}
...
}
...
task.stack = null;
}
如果不是從Activity調(diào)用startActivity,那么目標Activity就不知道自己該屬于哪個TaskRecord,所以得指定FLAG_ACTIVITY_NEW_TASK,就會新建一個TaskRecord