美文网首页
Android Activity的启动过程-4 之 Activi

Android Activity的启动过程-4 之 Activi

作者: 行走中的3卡 | 来源:发表于2023-07-31 15:44 被阅读0次

以下文章基于 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
(文中的分析不错,但是代码比较旧)

相关文章

网友评论

      本文标题:Android Activity的启动过程-4 之 Activi

      本文链接:https://www.haomeiwen.com/subject/mzbepdtx.html