本文基于Android 7.0
每一个ActivityRecord都会有一个Activity与之对应,一个Activity可能会有多个ActivityRecord,因为Activity可以被多次实例化,取决于其launchmode。一系列相关的ActivityRecord组成了一个TaskRecord,TaskRecord是存在于ActivityStack中,ActivityStackSupervisor是用来管理这些ActivityStack的。
下面是一个简单的关系图
可以看到一个ActivityStack可以包含很多个TaskRecord,一个TaskRecord又可以包含很多个ActivityRecord。
下面看下ActivityRecord、TaskRecord、ActivityStack数据结构
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
...
ActivityRecord中还定义了activity的类型,一共有三种
static final int APPLICATION_ACTIVITY_TYPE = 0;
static final int HOME_ACTIVITY_TYPE = 1;
static final int RECENTS_ACTIVITY_TYPE = 2;
如何区分这三种类型的Activity呢?
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;
}
}
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);
...
}
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 mActivities;
//TaskRecord所在的stack
/** Current stack */
ActivityStack stack;
mActivities保存了该TaskRecord的所有ActivityRecord信息,同时每一个ActivityRecord都有其所在TaskRecord的引用。
在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;
}
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 mTaskHistory = new ArrayList<>();
...
final int mStackId;
...
/** Run all ActivityStacks through this */
final ActivityStackSupervisor mStackSupervisor;
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;
...
}
ActivityStack并不是开机就创建的,而是在需要时才创建。