App启动流程【3】ActivityTaskManagerService到ActivityStarter

632 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

上一篇文章 App启动流程【2】Activity 到 ActivityTaskManagerService 的调用流程 的最后来到了 ActivityTaskManagerService 中的 startActivity 方法中,继续向下分析。

ActivityTaskManagerService.startActivity

ActivityTaskManagerService 的 startActivity 方法:

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
        Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

startActivity 中转到 startActivityAsUser

@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
        String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
        Bundle bOptions, int userId) {
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
            true /*validateIncomingUser*/);
}

真实逻辑在私有的 startActivityAsUser 方法中:

private int startActivityAsUser(IApplicationThread caller, String callingPackage,
       @Nullable String callingFeatureId, Intent intent, String resolvedType,
       IBinder resultTo, String resultWho, int requestCode, int startFlags,
       ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
   assertPackageMatchesCallingUid(callingPackage);
   enforceNotIsolatedCaller("startActivityAsUser");

   userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

   // TODO: Switch to user app stacks here.
   return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
           .setCaller(caller)
           .setCallingPackage(callingPackage)
           .setCallingFeatureId(callingFeatureId)
           .setResolvedType(resolvedType)
           .setResultTo(resultTo)
           .setResultWho(resultWho)
           .setRequestCode(requestCode)
           .setStartFlags(startFlags)
           .setProfilerInfo(profilerInfo)
           .setActivityOptions(bOptions)
           .setUserId(userId)
           .execute();
}

这个方法中最核心的逻辑是通过 ActivityStartController 执行 execute 方法并返回一个 int 值。

ActivityStartController getActivityStartController() {
		return mActivityStartController;
}

mActivityStartController 的初始化在:

public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController, Looper looper) {
    // ...
    mActivityStartController = new ActivityStartController(this);
}

obtainStarter 方法返回的是一个 ActivityStarter 对象:

ActivityStarter obtainStarter(Intent intent, String reason) {
    return mFactory.obtain().setIntent(intent).setReason(reason);
}

ActivityStarter

ActivityStarter 是用于阐述如何启动 Activity 的 Controller 。此类包含了所有用于确定如何将 intent 和 flag 转换为 Activity 和它关联的任务栈信息的逻辑。

ActivityStarter 配置了一些信息后,执行 execute 方法,execute 方法的注释描述了这个方法的作用:

根据前面提供的请求参数解析必要的信息,并执行请求,开始 start 一个 Activity 的旅程。

int execute() {
    try {
        // 1. 拒绝可能泄露的文件描述符

        // 2. 更新 LaunchingState 

        // 3. 如果调用者尚未 resolveActivity ,我们会在这里这样做。 

        // 4. 为此关闭或重新启动尝试添加检查点,以便我们可以记录原始 intent 操作和包名称。

        int res;
        synchronized (mService.mGlobalLock) {
            // ...
            
            // Task 是一个 TaskFragment,可以包含一组 Activity 来执行特定的工作。
            // 相同 Task 关联的 Activity 通常分组在同一个 Task 中。 Task 也可以是在最近屏幕中显示的与用户交互的作业的实体。
            // Task 还可以包含其他 Task。
            final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
            if (rootTask != null) {
                rootTask.mConfigWillChange = globalConfigWillChange;
            }

            final long origId = Binder.clearCallingIdentity();
            // 如果这是一个重量级进程而已经有另一个不同的重量级进程在运行,则将请求日期到重量级切换。
            res = resolveToHeavyWeightSwitcherIfNeeded();
            if (res != START_SUCCESS) {
                return res;
            }
            // * 执行请求
            res = executeRequest(mRequest);

            Binder.restoreCallingIdentity(origId);

            // 更新配置
            
            // 通知 ActivityMetricsLogger ,Activity 已启动。然后 ActivityMetricsLogger 将等待 window 被绘制并填充 WaitResult。
            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
                    newActivityCreated, mLastStartActivityRecord, originalOptions);
            if (mRequest.waitResult != null) {
                mRequest.waitResult.result = res;
                res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
                        launchingState);
            }
            return getExternalResult(res);
        }
    } finally {
        onExecutionComplete();
    }
}

在核心逻辑执行前,会做一些准备工作:

  • 拒绝可能泄露的文件描述符
  • 更新 LaunchingState
  • 确保执行 resolveActivity
  • 添加 checkpoint ,记录原始的 intent 和包名。

然后是需要同步执行的核心部分:

  • 更新即将更新 flag
  • resolveToHeavyWeightSwitcherIfNeeded
  • executeRequest
  • Binder.restoreCallingIdentity(origId)
  • 更新配置
  • 通知 ActivityMetricsLogger Activity 已启动,等待 window 绘制并填充,返回 WaitResult 。
  • 返回 getExternalResult

这里比较核心的是 executeRequest

执行 Activity 启动请求并开始启动 Activity 的旅程。这里首先执行几个初步检查。

正常的 Activity 启动流程将通过 startActivityUnchecked 到 startActivityInner 。

过滤出关键逻辑:

    private int executeRequest(Request request) {

        // ...

        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, restrictedBgActivity, intentGrants);

        if (request.outActivity != null) {
            request.outActivity[0] = mLastStartActivityRecord;
        }

        return mLastStartActivityResult;
    }

在这个方法中,重点的两个逻辑是:

  1. 构造 ActivityRecord 对象,记录上一次最后启动记录
  2. 通过 startActivityUnchecked 继续启动 Activity

前者无需多言,继续跟进后者:

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            TaskFragment inTaskFragment, boolean restrictedBgActivity,
            NeededUriGrants intentGrants) {
        // ... 
        try {
            mService.deferWindowLayout();
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
                    intentGrants);
        } finally {
            startedActivityRootTask = handleStartResult(r, options, result, newTransition,
                    remoteTransition);
            mService.continueWindowLayout();
        }
        postStartActivityProcessing(r, result, startedActivityRootTask);

        return result;
    }

startActivityUnchecked 调用到了 startActivityInner :

启动一个 Activity 并决定如果 Activity 是否应该添加到已存在的 Task 顶部,还是发送一个新的 Intent 到一个已存在的 Activity 。

注意:这个方法应该只能从 startActivityUnchecked 调用

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,
        TaskFragment inTaskFragment, boolean restrictedBgActivity,
        NeededUriGrants intentGrants) {
    
    // ...

    // 获取 Target Root Task
    if (mTargetRootTask == null) {
        mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
    }

    // ...

    final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded();
    mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch, mOptions, sourceRecord);
    
    if (mDoResume) {
        final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
        if (!mTargetRootTask.isTopActivityFocusable() || (topTaskActivity != null && topTaskActivity.isTaskOverlay() && mStartActivity != topTaskActivity)) {
            mTargetRootTask.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS);
            mTargetRootTask.mDisplayContent.executeAppTransition();
        } else {
            if (mTargetRootTask.isTopActivityFocusable() && !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
                mTargetRootTask.moveToFront("startActivityInner");
            }
            // Activity 进入 resume 
            mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
        }
    }
    mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);

    // Activity 启动后更新最近任务列表
    mSupervisor.mRecentTasks.add(startedTask);
    mSupervisor.handleNonResizableTaskIfNeeded(startedTask, mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);

    // ...

    return START_SUCCESS;
}

在这个方法中,处理了 Activity 所依附的 Task 的相关逻辑,这里很复杂有兴趣可以自行查看这个方法的源码。本文只关注重点逻辑。

经过一系列的 Task 检查和构造后,通过 mTargetRootTask.startActivityLocked 方法继续进行核心的启动 Activity 逻辑。

在 Activity 启动后,通过 mRootWindowContainer.resumeFocusedTasksTopActivities(...) 使 Activity 获取焦点,然后更新 Task 栈,做完这些工作,最后的一个步骤是更新最近任务列表。

到这一步,启动 Activity 的核心逻辑就落到了 Task 类中。