以下文章基于 Android 13/14 源码. (20230801 codesearch main 分支)
在研究 Activity 启动流程,跟踪源码到 AMS 的时候,
会发现少不了 ActivityRecord/Task/TaskRecord/ActivityStack 等概念。
可以简单的理解为:都是Activity 在 AMS 上的各种封装,对APP 是透明 和 隔离的。
1. ActivityRecord
ActivityRecord 是应用层 Activity组件 在 AMS 中的代表,
每一个在应用中启动的 Activity,在AMS中都有一个 ActivityRecord 实例来与之对应,
这个 ActivityRecord 伴随着Activity的启动而创建,也伴随着Activity的终止而销毁。
1.1 ActivityRecord 源码
官方解释为:历史记录任务 中的 条目,表示活动。
继承 WindowToken, 表示是 通过 Binder 与 WMS 通信.
/**
* An entry in the history task, representing an activity.
*/
final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_ATM;
...
final ActivityTaskManagerService mAtmService;
@NonNull
final ActivityInfo info; // activity info provided by developer in AndroidManifest
// Which user is this running for?
final int mUserId;
// The package implementing intent's component
// TODO: rename to mPackageName
final String packageName;
// the intent component, or target of an alias.
final ComponentName mActivityComponent;
// Input application handle used by the input dispatcher.
private InputApplicationHandle mInputApplicationHandle;
final int launchedFromPid; // always the pid who started the activity.
final int launchedFromUid; // always the uid who started the activity.
final String launchedFromPackage; // always the package who started the activity.
final @Nullable String launchedFromFeatureId; // always the feature in launchedFromPackage
private final int mLaunchSourceType; // original launch source type
final Intent intent; // the original intent that generated us
final String shortComponentName; // the short component name of the intent
final String resolvedType; // as per original caller;
final String processName; // process where this component wants to run
final String taskAffinity; // as per ActivityInfo.taskAffinity
final boolean stateNotNeeded; // As per ActivityInfo.flags
...
可见,包含了 Activity 的各种信息,如 ActivityInfo 、mUserId、packageName、launchedFromPid、intent等等
1.2 ActivityRecord 创建
可能创建的地方:
(1) frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {
...
final Task focusedRootTask =
mRootWindowContainer.getTopDisplayFocusedRootTask();
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
mLastStartActivityRecord = r;
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, balCode, intentGrants)
可见,这个时候已经确定了 Activity 的最终 userId,
在调用 startActivityUnchecked 内部处理之前 创建了 ActivityRecord 对象,并且把它保存到历史 mLastStartActivityResult。
(2) frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/** Temporary array to capture start activity results */
private ActivityRecord[] tmpOutRecord = new ActivityRecord[1];
int startActivities(IApplicationThread caller, int callingUid, int incomingRealCallingPid...} {
...
final ActivityRecord[] outActivity = new ActivityRecord[1];
final int startResult = starters[i].setResultTo(resultTo)
.setOutActivity(outActivity).execute();
}
这个是在 启动 多个 Activity 时创建的, 可暂且忽略.
(3) frameworks/base/services/core/java/com/android/server/wm/Task.java
/** On Task switch, finds the top activity that supports PiP. */
@Nullable
static ActivityRecord findEnterPipOnTaskSwitchCandidate(@Nullable Task topTask) {
if (topTask == null) {
return null;
}
final ActivityRecord[] candidate = new ActivityRecord[1];
这个是在PIP 模式下创建的,也可暂且忽略.
参考:
https://juejin.cn/post/6856298463119409165
(文中的分析不错,但是代码比较旧)
网友评论