转自:https://i-blog.csdnimg.cn/blog_migrate/3773fdb28e4ec670a776fd7c9d48e3a8.png
本文基于Android 7.0
每一个ActivityRecord都会有一个Activity与之对应,一个Activity可能会有多个ActivityRecord,因为Activity可以被多次实例化,取决于其launchmode。一系列相关的ActivityRecord组成了一个TaskRecord,TaskRecord是存在于ActivityStack中,ActivityStackSupervisor是用来管理这些ActivityStack的。
下面是一个简单的关系图
可以看到一个ActivityStack可以包含很多个TaskRecord,一个TaskRecord又可以包含很多个ActivityRecord。
下面看下ActivityRecord、TaskRecord、ActivityStack数据结构
一、ActivityRecord
ActivityRecord包含了一个Activity的所有信息,比较重要的对象主要有
- frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
- //ams的引用
- final ActivityManagerService service; // owner
- //token用来和wms交互
- final IApplicationToken.Stub appToken; // window manager token
- final ActivityInfo info; // all about me
- final ApplicationInfo appInfo; // information about activity's app
- ...
- //Activity资源信息
- CharSequence nonLocalizedLabel; // the label information from the package mgr.
- int labelRes; // the label information from the package mgr.
- int icon; // resource identifier of activity's icon.
- int logo; // resource identifier of activity's logo.
- int theme; // resource identifier of activity's theme.
- int realTheme; // actual theme resource we will use, never 0.
- int windowFlags; // custom window flags for preview window.
- //ActivityRecord所在的TaskRecord
- TaskRecord task; // the task this is in.
- ...
- //ActivityRecord所在进程
- ProcessRecord app; // if non-null, hosting application
- ActivityState state; // current state we are in
- ...
其中task对象标识了所在的其所在的TaskRecord,这样ActivityRecord和TaskRecord就联系起来了。
ActivityRecord中还定义了activity的类型,一共有三种
- static final int APPLICATION_ACTIVITY_TYPE = 0;
- static final int HOME_ACTIVITY_TYPE = 1;
- static final int RECENTS_ACTIVITY_TYPE = 2;
- frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
- private void setActivityType(boolean componentSpecified,
- int launchedFromUid, Intent intent, ActivityRecord sourceRecord) {
- if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
- && isHomeIntent(intent) && !isResolverActivity()) {
- // This sure looks like a home activity!
- mActivityType = HOME_ACTIVITY_TYPE;
- } else if (realActivity.getClassName().contains(RECENTS_PACKAGE_NAME)) {
- mActivityType = RECENTS_ACTIVITY_TYPE;
- } else {
- mActivityType = APPLICATION_ACTIVITY_TYPE;
- }
- }
如果是launcher activity或者ResolverActivity(这是一个系统Activity,弹出的让用户选择app的界面,例如分享文件时弹出让用户选择分享到哪个应用),只有这两种Activity会设置为HOME_ACTIVITY_TYPE。RECENTS_ACTIVITY_TYPE是systemui里的RecentsActivity,除了这三个activity之外,其他的都属于APPLICATION_ACTIVITY_TYPE。
ActivityRecord是在startActivity时创建的
- frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
- final int startActivityLocked(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,
- ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
- TaskRecord inTask) {
- ...
- ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
- intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
- requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
- options, sourceRecord);
- ...
- }
二、TaskRecord
- frameworks/base/services/core/java/com/android/server/am/TaskRecord.java
- //TaskRecord的唯一标识
- final int taskId; // Unique identifier for this task.
- ...
- // This represents the last resolved activity values for this task
- // NOTE: This value needs to be persisted with each task
- TaskDescription lastTaskDescription = new TaskDescription();
- //TaskRecord里所有的ActivityRecord信息
- /** List of all activities in the task arranged in history order */
- final ArrayList<ActivityRecord> mActivities;
- //TaskRecord所在的stack
- /** Current stack */
- ActivityStack stack;
在startActivity时,也会创建TaskRecord
- frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
- private void setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
- mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags,
- mOptions);
- if (mReuseTask == null) {
- final TaskRecord task = mTargetStack.createTaskRecord(
- mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
- mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
- mNewTaskIntent != null ? mNewTaskIntent : mIntent,
- mVoiceSession, mVoiceInteractor, !mLaunchTaskBehind /* toTop */);
- mStartActivity.setTask(task, taskToAffiliate);
- ...
- } else {
- mStartActivity.setTask(mReuseTask, taskToAffiliate);
- }
- }
- frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
- TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- boolean toTop) {
- TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
- voiceInteractor);
- // add the task to stack first, mTaskPositioner might need the stack association
- addTask(task, toTop, "createTaskRecord");
- ...
- return task;
- }
当没有可复用的TaskRecord时(假如第一次跑进来,肯定是没有的,必须要创建),就会创建一个TaskRecord,mStartActivity是要启动的Activity的ActivityRecord,通过其setTask就把ActivityRecord绑定到了一个TaskRecord上
三、ActivityStack
- frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
- /**
- * The back history of all previous (and possibly still
- * running) activities. It contains #TaskRecord objects.
- */
- private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
- ...
- final int mStackId;
- ...
- /** Run all ActivityStacks through this */
- final ActivityStackSupervisor mStackSupervisor;
ActivityStack管理了一系列的TaskRecord,通过mStackId来唯一标识,持有ActivityStackSupervisor的引用。
ActivityStack的种类一共有5种
- frameworks/base/core/java/android/app/ActivityManager.java
- public static class StackId {
- /** Invalid stack ID. */
- public static final int INVALID_STACK_ID = -1;
- /** First static stack ID. */
- public static final int FIRST_STATIC_STACK_ID = 0;
- /** Home activity stack ID. */
- public static final int HOME_STACK_ID = FIRST_STATIC_STACK_ID;
- /** ID of stack where fullscreen activities are normally launched into. */
- public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
- /** ID of stack where freeform/resized activities are normally launched into. */
- public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1;
- /** ID of stack that occupies a dedicated region of the screen. */
- public static final int DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID + 1;
- /** ID of stack that always on top (always visible) when it exist. */
- public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;
- /** Last static stack stack ID. */
- public static final int LAST_STATIC_STACK_ID = PINNED_STACK_ID;
- ...
- }
HOME_STACK_ID标识的ActivityStack主要维护了launcheractivity和recentactivity所在的TaskRecord,FREEFORM_WORKSPACE_STACK_ID标识的ActivityStack主要维护了FREEFORM模式下的TaskRecord,分屏的应用进入分屏模式后会在DOCKED_STACK_ID标识的ActivityStack中,进入画中画模式之后会在PINNED_STACK_ID标识的ActivityStack中。一般情况下,我们接触到的绝大部分都是在FULLSCREEN_WORKSPACE_STACK_ID(全屏显示)标识的ActivityStack中。
ActivityStack并不是开机就创建的,而是在需要时才创建。