以下文章基于 Android 13/14 源码. (20230801 codesearch main 分支)
在研究 Activity 启动流程,跟踪源码到 AMS 的时候,
会发现少不了 ActivityRecord /Task/ActivityStack 等概念。
可以简单的理解为:都是Activity 在 AMS 上的各种封装,对APP 是透明 和 隔离的。
1. Task
参考之前文章的介绍:
https://www.jianshu.com/p/2293c6f7811f (Activity - 任务(Task)和返回堆栈(back stack) -(1)基本概念)
任务是用户在执行某项工作时与之互动的一系列 Activity 的集合 (正确说是针对 ActivityRecord)
(可以参考Tasks & Back stack 的系列文章)
1.1 Task 源码
frameworks/base/services/core/java/com/android/server/wm/Task.java
在 system_server 进程中, 继承自 TaskFragment。
属于 ATMS 系列.
package com.android.server.wm;
/**
* {@link Task} is a TaskFragment that can contain a group of activities to perform a certain job.
* Activities of the same task affinities usually group in the same {@link Task}. A {@link Task}
* can also be an entity that showing in the Recents Screen for a job that user interacted with.
* A {@link Task} can also contain other {@link Task}s.
*/
class Task extends TaskFragment {
private static final String TAG = TAG_WITH_CLASS_NAME ? "Task" : TAG_ATM;
String affinity; // The affinity name for this task, or null; may change identity.
Intent intent; // The original intent that started the task. Note that this value can
// be null.
Intent affinityIntent; // Intent of affinity-moved activity that started this task.
ComponentName origActivity; // The non-alias activity component of the intent.
ComponentName realActivity; // The actual activity component that started the task.
// For relaunching the task from recents as though it was launched by the original launcher.
int mCallingUid;
String mCallingPackage;
String mCallingFeatureId;
/* Unique identifier for this task. */
final int mTaskId;
/* User for which this task was created. */
// TODO: Make final
int mUserId;
...
它的构造函数:
private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent,
Intent _affinityIntent, String _affinity, String _rootAffinity,
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId, int _effectiveUid,
String _lastDescription, long lastTimeMoved, boolean neverRelinquishIdentity,
TaskDescription _lastTaskDescription, PersistedTaskSnapshotData _lastSnapshotData,
int taskAffiliation, int prevTaskId, int nextTaskId, int callingUid,
String callingPackage, @Nullable String callingFeatureId, int resizeMode,
boolean supportsPictureInPicture, boolean _realActivitySuspended,
boolean userSetupComplete, int minWidth, int minHeight, ActivityInfo info,
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
boolean _createdByOrganizer, IBinder _launchCookie, boolean _deferTaskAppear,
boolean _removeWithTaskOrganizer) {
super(atmService, null /* fragmentToken */, _createdByOrganizer, false /* isEmbedded */);
mTaskId = _taskId;
mUserId = _userId;
mResizeMode = resizeMode;
mSupportsPictureInPicture = supportsPictureInPicture;
包含调用者等信息, 封装 Activity 的是在 父类 TaskFragment
1.2 Task 的父类 TaskFragment
frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
封装了一系列的 Acitivty , 并且管理它们的生命周期即可见性.
package com.android.server.wm;
/**
* A basic container that can be used to contain activities or other {@link TaskFragment}, which
* also able to manage the activity lifecycle and updates the visibilities of the activities in it.
*/
class TaskFragment extends WindowContainer<WindowContainer> {
final ActivityTaskManagerService mAtmService;
final ActivityTaskSupervisor mTaskSupervisor;
final RootWindowContainer mRootWindowContainer;
private final TaskFragmentOrganizerController mTaskFragmentOrganizerController;
private ActivityRecord mPausingActivity = null;
ActivityRecord mLastPausedActivity = null;
private ActivityRecord mResumedActivity = null;
}
它的构造函数:
/** Creates an embedded task fragment. */
TaskFragment(ActivityTaskManagerService atmService, IBinder fragmentToken,
boolean createdByOrganizer) {
this(atmService, fragmentToken, createdByOrganizer, true /* isEmbedded */);
}
TaskFragment(ActivityTaskManagerService atmService, IBinder fragmentToken,
boolean createdByOrganizer, boolean isEmbedded) {
super(atmService.mWindowManager);
mAtmService = atmService;
mTaskSupervisor = mAtmService.mTaskSupervisor;
mRootWindowContainer = mAtmService.mRootWindowContainer;
mCreatedByOrganizer = createdByOrganizer;
mIsEmbedded = isEmbedded;
mRelativeEmbeddedBounds = isEmbedded ? new Rect() : null;
mTaskFragmentOrganizerController =
mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController;
mFragmentToken = fragmentToken;
mRemoteToken = new RemoteToken(this);
}
一些获取 ActivityRecord 的关键函数, 例如最顶层的.
ActivityRecord topRunningActivity() {
return topRunningActivity(false /* focusableOnly */);
}
ActivityRecord topRunningActivity(boolean focusableOnly) {
return topRunningActivity(focusableOnly, true /* includingEmbeddedTask */);
}
其中 getActivity 的操作又在它的父类 WindowContainer 里
frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
1.2 Task 的父类 TaskFragment 的父类 WindowContainer
package com.android.server.wm;
/**
* Defines common functionality for classes that can hold windows directly or through their
* children in a hierarchy form.
* The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime
* changes are made to this class.
*/
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,
InsetsControlTarget {
// List of children for this window container. List is in z-order as the children appear on
// screen with the top-most window container at the tail of the list.
protected final WindowList<E> mChildren = new WindowList<E>();
ActivityRecord getActivity(Predicate<ActivityRecord> callback, boolean traverseTopToBottom,
ActivityRecord boundary) {
if (traverseTopToBottom) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer wc = mChildren.get(i);
// TODO(b/156986561): Improve the correctness of the boundary check.
if (wc == boundary) return boundary;
final ActivityRecord r = wc.getActivity(callback, traverseTopToBottom, boundary);
if (r != null) {
return r;
}
}
} else {
final int count = mChildren.size();
for (int i = 0; i < count; i++) {
final WindowContainer wc = mChildren.get(i);
// TODO(b/156986561): Improve the correctness of the boundary check.
if (wc == boundary) return boundary;
final ActivityRecord r = wc.getActivity(callback, traverseTopToBottom, boundary);
if (r != null) {
return r;
}
}
}
return null;
}
与 Task相关联的 有 Acitivty 的 LaunchMode 启动模式
2. 已删除的 TaskRecord
TaskRecord 在新的OS 已经被删除或者 改名了?
==> Android ROS (11) 上已经没有了这个类. 将它的代码移到了 Task 和它的的父类 TaskFragment / WindowContainer.
2.1 Android 10 上的 TaskRecord 源码
Android Q(10) 上:
frameworks/base/services/core/java/com/android/server/wm/TaskRecord.java
class TaskRecord extends ConfigurationContainer {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_ATM;
final int taskId; // Unique identifier for this task.
String affinity; // The affinity name for this task, or null; may change identity.
String rootAffinity; // Initial base affinity, or null; does not change from initial root.
ComponentName origActivity; // The non-alias activity component of the intent.
ComponentName realActivity; // The actual activity component that started the task.
// For relaunching the task from recents as though it was launched by the original launcher.
int mCallingUid;
String mCallingPackage;
// TODO: remove after unification
Task mTask;
它的构造函数
/**
* Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
* ActivityInfo, Intent, TaskDescription)} instead.
*/
TaskRecord(ActivityTaskManagerService service, int _taskId, ActivityInfo info, Intent _intent,
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
mService = service;
userId = UserHandle.getUserId(info.applicationInfo.uid);
taskId = _taskId;
lastActiveTime = SystemClock.elapsedRealtime();
mAffiliatedTaskId = _taskId;
voiceSession = _voiceSession;
voiceInteractor = _voiceInteractor;
isAvailable = true;
mActivities = new ArrayList<>();
mCallingUid = info.applicationInfo.uid;
mCallingPackage = info.packageName;
setIntent(_intent, info);
setMinDimensions(info);
touchActiveTime();
mService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
}
2.2 Android 10 上的 Task 源码
这里就比较简单:
frameworks/base/services/core/java/com/android/server/wm/Task.java
class Task extends WindowContainer<AppWindowToken> implements ConfigurationContainerListener{
static final String TAG = TAG_WITH_CLASS_NAME ? "Task" : TAG_WM;
// TODO: Track parent marks like this in WindowContainer.
TaskStack mStack;
final int mTaskId;
final int mUserId;
// TODO: remove after unification
TaskRecord mTaskRecord;
Task(int taskId, TaskStack stack, int userId, WindowManagerService service, int resizeMode,
boolean supportsPictureInPicture, TaskDescription taskDescription,
TaskRecord taskRecord) {
super(service);
mTaskId = taskId;
mStack = stack;
mUserId = userId;
mResizeMode = resizeMode;
mSupportsPictureInPicture = supportsPictureInPicture;
mTaskRecord = taskRecord;
if (mTaskRecord != null) {
// This can be null when we call createTaskInStack in WindowTestUtils. Remove this after
// unification.
mTaskRecord.registerConfigurationChangeListener(this);
}
setBounds(getRequestedOverrideBounds());
mTaskDescription = taskDescription;
// Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
setOrientation(SCREEN_ORIENTATION_UNSET);
}
从代码上看,Task 和 TaskRecord 会相互持有对象.
TaskRecord 中:
// TODO: remove after unification
Task mTask;
Task 中:
// TODO: remove after unification
TaskRecord mTaskRecord;
从这里的注释也可知,它们两将会统一.
3. 小结
Android ROS (12) 以后,我们只需关心 Task 就可以了.
旧OS 上的 TaskRecord 的文章,也可以作为参考
99.参考:
https://juejin.cn/post/6856298463119409165
(文中的分析不错,但是代码比较旧)
https://blog.csdn.net/hfreeman2008/article/details/113309272