Android6.0 AMS启动Activity(四) AMS内部一些成员变量
来源:互联网 发布:淘宝三个月前订单不见 编辑:程序博客网 时间:2024/05/18 00:35
之前在分析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); }
- Android6.0 AMS启动Activity(四) AMS内部一些成员变量
- Android6.0 AMS启动Activity(四) AMS内部成员变量
- Android6.0 AMS启动Activity(三) 进程内部启动Activity
- Android6.0 AMS启动Activity(三) 进程内部启动Activity
- Android6.0 AMS启动Activity(六) AMS与PKMS关系(通过Intent获取ActivityInfo)
- Android6.0 AMS启动Activity(六) AMS与PKMS关系(通过Intent获取ActivityInfo)
- Android6.0之AMS启动
- Android6.0 AMS启动Activity(二) 启动进程然后启动Activity
- Android6.0 AMS启动Activity(二) 启动进程然后启动Activity
- Android6.0 AMS启动Activity(一) 启动Activity两种方式
- Android6.0 AMS启动Activity(五) 在新进程中启动Activity
- Android6.0 AMS启动Activity(一) 启动Activity两种方式
- Android6.0 AMS 新进程中启动Activity
- Android6.0之AMS启动App下篇
- AMS启动Activity过程
- Activity启动过程(一)AMS
- AMS (3): AMS 如何管理Activity?
- Android6.0之AMS前奏
- SVN分支与合并透析
- 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)
- spring 动态 多数据源 数据库 (datasource )配置
- [读书笔记]Android中的TableLayout
- iOS 报错:没有查看权限the file "xxx.app" couldn't be opened because you don't have permission to view it.
- Android6.0 AMS启动Activity(四) AMS内部一些成员变量
- MySQL数据库主从(Master/Slave)同步安装与配置
- React事件代理
- Aggressive cows(二分查找最大化最小值)
- 日常整理
- 为什么需要使用并发编程?什么时候适合使用并发编程技术?
- 如何优化内存?Unity中的内存种类;冯乐乐的总结的优化技术。
- Android异步处理常用方法
- android 微信6.2.0 AndroidManifest.xml