之前在分析AMS和ActivityStackSupervisor和ActivityStack对一些成员变量比较模糊,这篇博客主要讲下这些成员变量
一、AMS成员变量的初始化
我们先来看看AMS在systemServer的构造,初始化,先是调用了在SystemServiceManager中调用了AMS的构造函数。
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
构造函数主要是初始化了一些成员变量,下面我们来看如下两个成员变量,mRecenTasks代表最近的几个task
mRecentTasks = new RecentTasks(this);
mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
在ActivityStackSupervisor的构造函数就是创建了一个handler,然后把service和recentTasks保存在成员变量中。
public ActivityStackSupervisor(ActivityManagerService service, RecentTasks recentTasks) {
mService = service;
mRecentTasks = recentTasks;
mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
}
随后在SystemServer中会调用如下代码,就是把SystemServer这个进程保存进程信息。
mActivityManagerService.setSystemProcess();
再后面我们看下如下代码,把WMS对象设置到AMS中去。
mActivityManagerService.setWindowManager(wm);
看下AMS的setWindowManager函数,保存了WMS,然后调用了ActivityStackSupervisor的setWindowManager函数。
public void setWindowManager(WindowManagerService wm) {
mWindowManager = wm;
mStackSupervisor.setWindowManager(wm);
}
看下ActivityStackSupervisor的setWindowManager函数,在这个函数中先获取所有的显示设备,然后一一对应创建ActivityDisplay对象,接着调用createStackOnDisplay对象创建获取displayId的ActivityContainer,在ActivityContainer中又创建了ActivitStack对象。
void setWindowManager(WindowManagerService wm) {
synchronized (mService) {
mWindowManager = wm;
mDisplayManager =
(DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(this, null);
Display[] displays = mDisplayManager.getDisplays();//获取所有的显示设备
for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
final int displayId = displays[displayNdx].getDisplayId();
ActivityDisplay activityDisplay = new ActivityDisplay(displayId);//每一个显示设备创建一个对象的ActivityDisplay
if (activityDisplay.mDisplay == null) {
throw new IllegalStateException("Default Display does not exist");
}
mActivityDisplays.put(displayId, activityDisplay);
}
createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);//创建ActivityStack
mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
// Initialize this here, now that we can get a valid reference to PackageManager.
mLeanbackOnlyDevice = isLeanbackOnlyDevice();
}
}
在createStackOnDisplay函数,会获取传入的displayId获取activityDisplay ,然后创建一个ActivityContainer在这个对象的构造函数中会创建一个ActivityStack对象,最后调用attachToDisplayLocked把这个activityDisplay和activityContainer 联系起来。
ActivityStack createStackOnDisplay(int stackId, int displayId) {
ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);
if (activityDisplay == null) {
return null;
}
ActivityContainer activityContainer = new ActivityContainer(stackId);
mActivityContainers.put(stackId, activityContainer);//把activityContainer放入mActivityContainers中
activityContainer.attachToDisplayLocked(activityDisplay);
return activityContainer.mStack;
}
我们再来看下ActivityContainer 的attachToDisplayLocked函数,ActivityStack的mStacks是每一个显示设备上所有的ActivityStack。
void attachToDisplayLocked(ActivityDisplay activityDisplay) {
if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
+ " to display=" + activityDisplay);
mActivityDisplay = activityDisplay;
mStack.mDisplayId = activityDisplay.mDisplayId;
mStack.mStacks = activityDisplay.mStacks;
activityDisplay.attachActivities(mStack);
mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);
}
我们再来看ActivityDisplay的attachActivities函数,把当前的ActivityStack放在ActivityDisplay的mStacks中。
void attachActivities(ActivityStack stack) {
if (DEBUG_STACK) Slog.v(TAG_STACK,
"attachActivities: attaching " + stack + " to displayId=" + mDisplayId);
mStacks.add(stack);
}
所以每一个ActivityStack的mStacks变量代表的是这个显示设备上所有的ActivityStack。
然后我们再来看下面这句,调用getStack,传入的stackId就是HOME_STACK_ID,这样刚才创建的ActivityStack就赋给这些成员变量。这里mHomeStack就不会改变了,然后mFocusedStack和mLastFocusedStack会改变的。
mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);
二、startActivity流程
之前分析startActivity的时候,最后在ActivityStackSupervisor的startActivityUncheckedLocked函数分为两种情况,一种就是需要新建TaskRecord,另一种不需要新建TaskRecord。
2.1 需要创建新TaskRecord
现在我们再来看startActivity流程,回顾下在ActivityStackSupervisor的startActivityUncheckedLocked函数中,当需要创建一个新的task的时候,到如下代码线调用computeStackFocus函数创建了一个ActivityStack,然后调用ActivityStack的moveToFront函数
if (r.resultTo == null && inTask == null && !addingToTask
&& (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
targetStack = computeStackFocus(r, newTask);//创建ActivityStack
targetStack.moveToFront("startingNewTask");//将当前的ActivityStack放在最前面
if (reuseTask == null) {
r.setTask(targetStack.createTaskRecord(getNextTaskId(),
newTaskInfo != null ? newTaskInfo : r.info,
newTaskIntent != null ? newTaskIntent : intent,
voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
taskToAffiliate);
if (DEBUG_TASKS) Slog.v(TAG_TASKS,
"Starting new activity " + r + " in new task " + r.task);
} else {
r.setTask(reuseTask, taskToAffiliate);
}
if (isLockTaskModeViolation(r.task)) {
Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
if (!movedHome) {
if ((launchFlags &
(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
// Caller wants to appear on home activity, so before starting
// their own activity we will bring home to the front.
r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
}
}
}
我们先来看computeStackFocus函数,先是获取ActivityRecord的task对象,这个时候我们需要建一个task,所以显然为null。这个函数就是寻找合适的ActivityStack,最后没找到就调用createStackOnDisplay函数创建一个ActivityContainer对象,当然也就创建了ActivityStack对象了。
ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
final TaskRecord task = r.task;//为null
// On leanback only devices we should keep all activities in the same stack.
if (!mLeanbackOnlyDevice &&
(r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
ActivityStack stack;
if (task != null && task.stack != null) {//如果当前TaskRecord中有stack,这里显然没有
stack = task.stack;
if (stack.isOnHomeDisplay()) {
if (mFocusedStack != stack) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Setting " + "focused stack to r=" + r
+ " task=" + task);
} else {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Focused stack already=" + mFocusedStack);
}
}
return stack;
}
final ActivityContainer container = r.mInitialActivityContainer;
if (container != null) {
// The first time put it on the desired stack, after this put on task stack.
r.mInitialActivityContainer = null;
return container.mStack;
}
if (mFocusedStack != mHomeStack && (!newTask ||//mFousedStack不是HomeStack,而且不是新建Task
mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Have a focused stack=" + mFocusedStack);
return mFocusedStack;
}
final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;//所有设备上的ActivityStack
for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
stack = homeDisplayStacks.get(stackNdx);
if (!stack.isHomeStack()) {//如果StackId不是HOME_STACK_ID
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
"computeStackFocus: Setting focused stack=" + stack);
return stack;
}
}
// Need to create an app stack for this user.
stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);//最后还是没找到创建一个ActivityContainer对象
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
+ r + " stackId=" + stack.mStackId);
return stack;
}
return mHomeStack;
}
然后我们再来看下ActivityStack的moveToFront函数,先看看当前是否是HOME_STACK_ID的Stack,如果不是将当前的stack放在mStacks的最前面。mStacks之前看过代表这个显示设备上所有的Stack.
final void moveToFront(String reason) {
if (isAttached()) {
final boolean homeStack = isHomeStack()//看是否是HOME_STACK_ID的Stack
|| (mActivityContainer.mParentActivity != null
&& mActivityContainer.mParentActivity.isHomeActivity());
ActivityStack lastFocusStack = null;
if (!homeStack) {
// Need to move this stack to the front before calling
// {@link ActivityStackSupervisor#moveHomeStack} below.
lastFocusStack = mStacks.get(mStacks.size() - 1);//获取最后的Stack
mStacks.remove(this);//去除当前stack
mStacks.add(this);//再加入,这样当前的stack就在最前面了
}
// TODO(multi-display): Focus stack currently adjusted in call to move home stack.
// Needs to also work if focus is moving to the non-home display.
if (isOnHomeDisplay()) {//是否是默认显示设备
mStackSupervisor.moveHomeStack(homeStack, reason, lastFocusStack);
}
final TaskRecord task = topTask();
if (task != null) {
mWindowManager.moveTaskToTop(task.taskId);//通知wms
}
}
}
我们再来看看ActivityStackSuperVisor的moveHomeStack函数,这里就是主要是赋值mLastFocusedStack 和 mFocusedStack 。mFocusedStack 就是上面函数刚刚放到mStacks中去的那个ActivityStack,mLastFocusedStack 就是上一个mStacks的最前面的ActivityStack。
void moveHomeStack(boolean toFront, String reason, ActivityStack lastFocusedStack) {
ArrayList<ActivityStack> stacks = mHomeStack.mStacks;
final int topNdx = stacks.size() - 1;
if (topNdx <= 0) {
return;
}
// The home stack should either be at the top or bottom of the stack list.
if ((toFront && (stacks.get(topNdx) != mHomeStack))
|| (!toFront && (stacks.get(0) != mHomeStack))) {
if (DEBUG_STACK) Slog.d(TAG_STACK, "moveHomeTask: topStack old="
+ ((lastFocusedStack != null) ? lastFocusedStack : stacks.get(topNdx))
+ " new=" + mFocusedStack);
stacks.remove(mHomeStack);
stacks.add(toFront ? topNdx : 0, mHomeStack);
}
if (lastFocusedStack != null) {
mLastFocusedStack = lastFocusedStack;
}
mFocusedStack = stacks.get(topNdx);
再来继续看ActivityStackSupervisor的startActivityUncheckedLocked函数,接下来就是来创建TaskRecord。然后调用ActivityRecord的setTask,把这个创建了TaskRecord作为ActivityRecord的task对象。
if (reuseTask == null) {
r.setTask(targetStack.createTaskRecord(getNextTaskId(),
newTaskInfo != null ? newTaskInfo : r.info,
newTaskIntent != null ? newTaskIntent : intent,
voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
taskToAffiliate);
if (DEBUG_TASKS) Slog.v(TAG_TASKS,
"Starting new activity " + r + " in new task " + r.task);
}
我们看ActivityStack的createTaskRecord函数,创建一个TaskRecord。然后调用addTask把TaskRecord保存下来。
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;
}
addTask先把当前的ActivityStack放在这TaskRecord的stack成员变量中,然后就是把这个TaskRecord放在mTaskHistory一个合适的位置。
void addTask(final TaskRecord task, final boolean toTop, boolean moving) {
task.stack = this;//把当前ActivityStack放在这TaskRecord的stack成员变量中
if (toTop) {
insertTaskAtTop(task, null);
} else {
mTaskHistory.add(0, task);
updateTaskMovement(task, false);
}
if (!moving && task.voiceSession != null) {
try {
task.voiceSession.taskStarted(task.intent, task.taskId);
} catch (RemoteException e) {
}
}
}
2.2 不需要新建TaskReocrd
我们还是看下ActivityStackSupervisor的startActivityUncheckedLocked函数,下面是不要创建新的TaskReocrd的流程。先直接从ActivityRecord的task获取TaskRecord对象。
然后从TaskRecord的stack获取ActivityStack对象。和上面流程一样,先调用ActivityStack的moveToFront将当前这个ActivityStack放在最前面,同时改变mFocusedStack和mLastFocusedStack的值。然后又看当前这个TaskRecord是否是当前ActivityStack最前面的。如果不是把它调整到最前面
} else if (sourceRecord != null) {
final TaskRecord sourceTask = sourceRecord.task;
if (isLockTaskModeViolation(sourceTask)) {
Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
targetStack = sourceTask.stack;
targetStack.moveToFront("sourceStackToFront");//把当前ActivityStack放在最前面
final TaskRecord topTask = targetStack.topTask();
if (topTask != sourceTask) {
targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,//把当前TaskRecord放在ActivityStack的最前面
r.appTimeTracker, "sourceTaskToFront");
}
三、将Activity放在TaskRecord的最前面
下面我们再来看ActivityStack的startActivityLocked函数有下面代码,会把当前要启动的Activity放在TaskRecord的最前面
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());
task.addActivityToTop(r);
task.setFrontOfTask();
四、保存TaskRecord到mRecentTasks
我们继续分析ActivityStatck的resumeTopActivityInnerLocked函数,先分析要启动的Activity已经有进程了,这里我会先调用mRecentTasks.addLocked把现在的TaskRecord保存在mRecentTasks代表最近启动的Task
if (next.app != null && next.app.thread != null) {
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next);
// This activity is now becoming visible.
mWindowManager.setAppVisibility(next.appToken, true);
// schedule launch ticks to collect information about slow apps.
next.startLaunchTickingLocked();
ActivityRecord lastResumedActivity =
lastStack == null ? null :lastStack.mResumedActivity;
ActivityState lastState = next.state;
mService.updateCpuStats();
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");
next.state = ActivityState.RESUMED;
mResumedActivity = next;
next.task.touchActiveTime();
mRecentTasks.addLocked(next.task);//保存TaskRecord在mRecentTasks
mService.updateLruProcessLocked(next.app, true, null);
updateLRUListLocked(next);
mService.updateOomAdjLocked();
......
try {
// Deliver all pending results.
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
next.app.thread.scheduleSendResult(next.appToken, a);
}
}
......
next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,//调用ActivityThread的函数
mService.isNextTransitionForward(), resumeAnimOptions);
那如果启动没有进程的Activity又是在哪保存TaskRecord到mRecentTasks的呢。如果没有进程会调用startSpecificActivityLocked函数,最后又到ActivityThread的main函数,又调用AMS的attachApplicationLocked函数。在AMS的attachApplicationLocked函数中又会调用ActivityStackSupervisor的attachApplicationLocked方法。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
在ActivityStackSupervisor的attachApplicationLocked方法中又调用了realStartActivityLocked方法,在realStartActivityLocked方法中会调用app.thread.scheduleLaunchActivity启动Activity,后面还会调用ActivityStac的minimalResumeActivityLocked方法。
在这个函数中调用了mRecentTasks.addLocked方法保存了TaskRecord,还保存了mResumedActivity。
void minimalResumeActivityLocked(ActivityRecord r) {
r.state = ActivityState.RESUMED;
if (DEBUG_STATES) Slog.v(TAG_STATES,
"Moving to RESUMED: " + r + " (starting new instance)");
r.stopped = false;
mResumedActivity = r;
r.task.touchActiveTime();
mRecentTasks.addLocked(r.task);
completeResumeLocked(r);
mStackSupervisor.checkReadyForSleepLocked();
setLaunchTime(r);
if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
"Launch completed; removing icicle of " + r.icicle);
}