Android Activity的启动过程-4 之 ActivityRecord

以下文章基于 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 通信.

package com.android.server.wm;
/**
 * 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 模式下创建的"数组",也可暂且忽略.

1.3 . ActivityRecord 创建的方式

通过内部静态类 Builder 创建:

    static class Builder {
        private final ActivityTaskManagerService mAtmService;
        private WindowProcessController mCallerApp;
        private int mLaunchedFromPid;
        private int mLaunchedFromUid;
        private String mLaunchedFromPackage;
        private String mLaunchedFromFeature;
        private Intent mIntent;
        private String mResolvedType;
        private ActivityInfo mActivityInfo;
        private Configuration mConfiguration;
        private ActivityRecord mResultTo;
        private String mResultWho;
        private int mRequestCode;
        private boolean mComponentSpecified;
        private boolean mRootVoiceInteraction;
        private ActivityOptions mOptions;
        private ActivityRecord mSourceRecord;
        private PersistableBundle mPersistentState;
        private TaskDescription mTaskDescription;
        private long mCreateTime;

        Builder(ActivityTaskManagerService service) {
            mAtmService = service;
        }

        Builder setCaller(@NonNull WindowProcessController caller) {
            mCallerApp = caller;
            return this;
        }

      ...
        Builder setLaunchedFromFeature(String fromFeature) {
            mLaunchedFromFeature = fromFeature;
            return this;
        }
       ....

        ActivityRecord build() {
            if (mConfiguration == null) {
                mConfiguration = mAtmService.getConfiguration();
            }
            return new ActivityRecord(mAtmService, mCallerApp, mLaunchedFromPid,
                    mLaunchedFromUid, mLaunchedFromPackage, mLaunchedFromFeature, mIntent,
                    mResolvedType, mActivityInfo, mConfiguration, mResultTo, mResultWho,
                    mRequestCode, mComponentSpecified, mRootVoiceInteraction,
                    mAtmService.mTaskSupervisor, mOptions, mSourceRecord, mPersistentState,
                    mTaskDescription, mCreateTime);
        }
    }

参考:
https://juejin.cn/post/6856298463119409165
(文中的分析不错,但是代码比较旧)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容