先来张简单的关系图:java
ActivityStack、TaskRecord、ActivityRecord关系图android
下面进入详细的代码分析,本文源码基于android 27。shell
ActivityRecord,源码中的注释介绍:An entry in the history stack, representing an activity.
翻译:历史栈中的一个条目,表明一个activity。app
frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener { final ActivityManagerService service; // owner final IApplicationToken.Stub appToken; // window manager token AppWindowContainerController mWindowContainerController; final ActivityInfo info; // all about me final ApplicationInfo appInfo; // information about activity's app //省略其余成员变量 //ActivityRecord所在的TaskRecord private TaskRecord task; // the task this is in. //构造方法,须要传递大量信息 ActivityRecord(ActivityManagerService _service, ProcessRecord _caller, int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType, ActivityInfo aInfo, Configuration _configuration, com.android.server.am.ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified, boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor, ActivityOptions options, com.android.server.am.ActivityRecord sourceRecord) { } }
startActivity()时会建立一个ActivityRecord:this
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java class ActivityStarter { private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, com.android.server.am.ActivityRecord[] outActivity, TaskRecord inTask) { //其余代码略 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, options, sourceRecord); //其余代码略 } }
TaskRecord,内部维护一个ArrayList<ActivityRecord>用来保存ActivityRecord。google
frameworks/base/services/core/java/com/android/server/am/TaskRecord.java final class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener { final int taskId; //任务ID final ArrayList<ActivityRecord> mActivities; //使用一个ArrayList来保存全部的ActivityRecord private ActivityStack mStack; //TaskRecord所在的ActivityStack //构造方法 TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent, IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, int type) { } //添加Activity到顶部 void addActivityToTop(com.android.server.am.ActivityRecord r) { addActivityAtIndex(mActivities.size(), r); } //添加Activity到指定的索引位置 void addActivityAtIndex(int index, ActivityRecord r) { //... r.setTask(this);//为ActivityRecord设置TaskRecord,就是这里创建的联系 //... index = Math.min(size, index); mActivities.add(index, r);//添加到mActivities //... } //其余代码略 }
startActivity()时也会建立一个TaskRecord:spa
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java class ActivityStarter { private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate, int preferredLaunchStackId, ActivityStack topStack) { mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags, mOptions); if (mReuseTask == null) { //建立一个createTaskRecord,其实是调用ActivityStack里面的createTaskRecord()方法,ActivityStack下面会讲到 final TaskRecord task = mTargetStack.createTaskRecord( mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType); //其余代码略 } } }
ActivityStack,内部维护了一个ArrayList<TaskRecord>,用来管理TaskRecord。翻译
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java class ActivityStack<T extends StackWindowController> extends ConfigurationContainer implements StackWindowListener { private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();//使用一个ArrayList来保存TaskRecord final int mStackId; protected final ActivityStackSupervisor mStackSupervisor;//持有一个ActivityStackSupervisor,全部的运行中的ActivityStacks都经过它来进行管理 //构造方法 ActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId, ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) { } TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, boolean toTop, int type) { //建立一个task TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession, voiceInteractor, type); //将task添加到ActivityStack中去 addTask(task, toTop, "createTaskRecord"); //其余代码略 return task; } //添加Task void addTask(final TaskRecord task, final boolean toTop, String reason) { addTask(task, toTop ? MAX_VALUE : 0, true /* schedulePictureInPictureModeChange */, reason); //其余代码略 } //添加Task到指定位置 void addTask(final TaskRecord task, int position, boolean schedulePictureInPictureModeChange, String reason) { mTaskHistory.remove(task);//若存在,先移除 //... mTaskHistory.add(position, task);//添加task到mTaskHistory task.setStack(this);//为TaskRecord设置ActivityStack //... } //其余代码略 }
ActivityStack是由ActivityStackSupervisor来建立的,实际ActivityStackSupervisor就是用来管理ActivityStack的,继续看下面的ActivityStackSupervisor分析。3d
ActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的。code
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener { ActivityStack mHomeStack;//管理的是Launcher相关的任务 ActivityStack mFocusedStack;//管理非Launcher相关的任务 //建立ActivityStack ActivityStack createStack(int stackId, ActivityStackSupervisor.ActivityDisplay display, boolean onTop) { switch (stackId) { case PINNED_STACK_ID: //PinnedActivityStack是ActivityStack的子类 return new PinnedActivityStack(display, stackId, this, mRecentTasks, onTop); default: //建立一个ActivityStack return new ActivityStack(display, stackId, this, mRecentTasks, onTop); } } }
AMS初始化时会建立一个ActivityStackSupervisor对象。
因此,实际上,他们的关系应该是这样的:
ActivityStack、TaskRecord、ActivityRecord、ActivityStackSupervisor关系图
下面经过启动Activity的代码来分析一下:
首先,咱们看下处于桌面时的状态,运行命令:
adb shell dumpsys activity
结果以下:
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities) Display #0 (activities from top to bottom): Stack #0: //中间省略其余... Task id #102 //中间省略其余... TaskRecord{446ae9e #102 I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 StackId=0 sz=1} Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.apps.nexuslauncher/.NexusLauncherActivity } Hist #0: ActivityRecord{54fa22 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t102} Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.apps.nexuslauncher/.NexusLauncherActivity } ProcessRecord{19c7c43 2203:com.google.android.apps.nexuslauncher/u0a22} Running activities (most recent first): TaskRecord{446ae9e #102 I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 StackId=0 sz=1} Run #0: ActivityRecord{54fa22 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t102} mResumedActivity: ActivityRecord{54fa22 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t102} //省略其余
实际上就是以下图所示的结构,这里的Stack #0就是ActivityStackSupervisor中的mHomeStack,mHomeStack管理的是Launcher相关的任务。
桌面下的状态
从桌面启动一个APP,而后运行上面的命令,为了节省篇幅,这里和后面就不贴结果了,直接放图了。
从桌面点击图标启动一个AActivity,能够看到,会多了一个Stack #1,这个Stack #1就是ActivityStackSupervisor中的mFocusedStack,mFocusedStack负责管理的是非Launcher相关的任务。同时也会建立一个新的ActivityRecord和TaskRecord,ActivityRecord放到TaskRecord中,TaskRecord则放进mFocusedStack中。
启动A
而后,咱们从AActivity中启动一个BActivity,能够看到会建立一个新的ActivityRecord而后放到已有的TaskRecord栈顶。
默认(standerd)模式启动B
若是咱们想启动的BActivity在一个新的栈中呢,咱们能够用singleInstance的方式来启动BActivity。singleInstance后面也会讲到。这种方式会建立一个新的ActivityRecord和TaskRecord,把ActivityRecord放到新的TaskRecord中去。
启动新Task
这里对启动Activity过程当中涉及到的ActivityStack、TaskRecord、ActivityRecord、ActivityStackSupervisor进行简单的分析,实际上一张时序图就能够看明白了。相关的代码能够看上面的内容。
Activity启动UML类图
简单总结:
1.startActivity时首先会建立一个ActivityRecord。
2.若是有须要,会建立一个TaskRecord,并把这个TaskRecord加入到ActivityStack中。
3.将ActivityRecord添加到TaskRecord的栈顶。
相信看完上面的介绍,如今再来看启动模式那是so easy了。
默认模式,每次启动Activity都会建立一个新的Activity实例。
好比:如今有个A Activity,咱们在A上面启动B,再而后在B上面启动A,其过程如图所示:
standerd
若是要启动的Activity已经在栈顶,则不会从新建立Activity,只会调用该该Activity的onNewIntent()方法。
若是要启动的Activity不在栈顶,则会从新建立该Activity的实例。
好比:如今有个A Activity,咱们在A以standerd模式上面启动B,而后在B上面以singleTop模式启动A,其过程如图所示,这里会新建立一个A实例:
singleTop_A
若是在B上面以singleTop模式启动B的话,则不会从新建立B,只会调用onNewIntent()方法,其过程如图所示:
singleTop_B.png
若是要启动的Activity已经存在于它想要归属的栈中,那么不会建立该Activity实例,将栈中位于该Activity上的全部的Activity出栈,同时该Activity的onNewIntent()方法会被调用。
若是要启动的Activity不存在于它想要归属的栈中,而且该栈存在,则会建立该Activity的实例。
若是要启动的Activity想要归属的栈不存在,则首先要建立一个新栈,而后建立该Activity实例并压入到新栈中。
好比:如今有个A Activity,咱们在A以standerd模式上面启动B,而后在B上面以singleTask模式启动A,其过程如图所示:
singleTask
基本和singleTask同样,不一样的是启动Activity时,首先要建立在一个新栈,而后建立该Activity实例并压入新栈中,新栈中只会存在这一个Activity实例。
好比:如今有个A Activity,咱们在A以singleInstance模式上面启动B,其过程如图所示:
singleInstance
另外,若是startActivity()时往Intent 中加入相应的标志来指定启动模式,这种方式的优先级会比在AndroidManifest中定义的优先级高;可是AndroidManifest中只能定义四种启动方式:standard、singleTop、singleTask、singleInstance,而Intent的flag则有不少种。具体的能够看看文档,咱们这里看看部分flag: