一、主要涉及4个类
1) ActivityRecord
源码注释:An entry in the history stack, representing an activity.
翻译一下:存在历史栈的一个实例,代表一个Activity。
2) TaskRecord
Activity栈,内部维护一个ArrayList
3) ActivityStack
并不是一个Activity栈,真正意义上的Activity栈是TaskRecord,这个类是负责管理各个Activity栈,内部维护一个ArrayList
4) ActivityStackSupervisor
内部持有一个ActivityStack,而ActivityStack内部也持有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 mActivities;
/** Current stack */
ActivityStack stack;
}
同样的道理,成员变量stack表示自己所在的ActivityStack
ActivityStack
final class ActivityStack {
private ArrayList 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里构造一个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模式不会创建新的TaskRecord
构造一个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为空时,会触发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调用startActivity,那么目标Activity就不知道自己该属于哪个TaskRecord,所以得指定FLAG_ACTIVITY_NEW_TASK,就会新建一个TaskRecord