之前在分析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);
- public void setWindowManager(WindowManagerService wm) {
- mWindowManager = wm;
- mStackSupervisor.setWindowManager(wm);
- }
- 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();
- }
- }
- 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);
- }
- 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);
- }
- 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;//把当前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);
- }