系统启动流程分析之Launcher应用启动流程分析(中)

1,357 阅读6分钟

「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战」。

今天是2022年2月15日,农历元宵节,祝各位程序员兄弟姐妹们,元宵节快乐,往后的日子红红火火,热热闹闹!!!

Launcher应用启动流程分析

前述

本篇接上篇Launcher应用启动流程分析(上)流程分析,上篇说到系统启动完成后,

  1. 会调用SystemServer类的startOtherServices函数,而在这个函数中会调用ActivityManagerService的systemReady函数,表明系统启动已经完成
  2. AMS.systemReady函数中调用ATMS服务的startHomeOnAllDisplays函数,从而最终会调用RootWindowContainner的startHomeOnTaskDisplayArea函数(针对于所有的显示设备,当然在此我们仅分析只有一个默认显示设备的情况),然后针对于这个显示设备的显示区域,会调用RootWindowContainer对象的startHomeOnTaskDisplayArea函数
  3. 在RootWindowContainer对象的startHomeOnTaskDisplayArea函数中,获取对应的action=Intent.ACTION_MAIN,category=Intent.CATEGORY_HOME的对应Intent对象的应用Activity对象,并最终传递给ActivityStartController对象的startHomeActivity函数
  4. 在ActivityStartController对象的startHomeActivity函数中,初始化一个ActivityStarter对象,并运行其execute函数 接下来,我们就从这边开始继续分析Launcher应用的启动流程

正文

确认在ActivityStartController对象的startHomeActivity函数代码

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
        TaskDisplayArea taskDisplayArea) {
    // 设置Home Activity的一些参数,这个Activity根据前述可知,其对应的Intent对象的
    // action=Intent.ACTION_MAIN,
    // category=Intent.CATEGORY_HOME
    // 根据我们的经验这个对应的是Launcher3应用的Launcher对象
    // 当然,从日志打印中可以看到,若安卓设备有设定Lock锁的情况下,
    // 此处会启动com.android.settings.FallbackHome对象,在这个对象类中,
    // 当用户通过手动或者其他方式解锁之后才会调用Launcher对象,在此处,我们不考虑这种情况
    final ActivityOptions options = ActivityOptions.makeBasic();
    // 设置Activity全屏
    options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
    if (!ActivityRecord.isResolverActivity(aInfo.name)) {
        // The resolver activity shouldn't be put in home stack because when the foreground is
        // standard type activity, the resolver activity should be put on the top of current
        // foreground instead of bring home stack to front.
        options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
    }
    // 设置Activity需要显示在的显示设备和显示设备的显示区域
    final int displayId = taskDisplayArea.getDisplayId();
    options.setLaunchDisplayId(displayId);
    options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken
            .toWindowContainerToken());

    // The home activity will be started later, defer resuming to avoid unneccerary operations
    // (e.g. start home recursively) when creating home stack.
    mSupervisor.beginDeferResume();
    final ActivityStack homeStack;
    try {
        // Make sure home stack exists on display area.
        // 创建一个ActivityStack堆栈,用作后续存放调用Activity堆栈
        homeStack = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
    } finally {
        mSupervisor.endDeferResume();
    }
    // 此处初始化一个ActivityStarter对象,并运行其execute函数
    mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
            .setOutActivity(tmpOutRecord)
            .setCallingUid(0)
            .setActivityInfo(aInfo)
            .setActivityOptions(options.toBundle())
            .execute();
    mLastHomeActivityStartRecord = tmpOutRecord[0];
    // 由于这个homeStack是刚刚初始化的,因此,此处mInResumeTopActivity为默认值false
    if (homeStack.mInResumeTopActivity) {
        // If we are in resume section already, home activity will be initialized, but not
        // resumed (to avoid recursive resume) and will stay that way until something pokes it
        // again. We need to schedule another resume.
        mSupervisor.scheduleResumeTopActivities();
    }
}

由上述的代码和备注可以看到,此处最终只会调用obtainStarter函数初始化一个ActivityStarter对象,最终调用其execute函数来初始化对应的Activity对象

int execute() {
    try {
        // ...... 判空操作代码省略

        int res;
        synchronized (mService.mGlobalLock) {
            // ...... 日志代码省略

            // 调用executeRequest函数
            res = executeRequest(mRequest);

            // ...... 功能无关代码省略
            
            // 获取最终的结果
            return getExternalResult(mRequest.waitResult == null ? res
                    : waitForResult(res, mLastStartActivityRecord));
        }
    } finally {
        // 当上述代码运行结束后,调用此函数onExecutionComplete,用作设置最终运行状态
        onExecutionComplete();
    }
}

如上代码可知,主要会做三个操作

  1. 调用executeRequest函数,运行Activity
  2. 调用getExternalResult函数,获取最终运行的结果
  3. 调用onExecutionComplete函数,主要用作运行结束后设置部分对象状态 此处,我们主要分析第一条,确认Launcher应用的启动过程
private int executeRequest(Request request) {
    // ...... 判空和初始化操作,此处省略

    // 初始化一个ActivityRecord对象
    final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
            callingPackage, callingFeatureId, intent, resolvedType, aInfo,
            mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
            request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
            sourceRecord);
    // 这边将本次启动的ActivityRecord对象赋值到Last ActivityRecord中保存
    mLastStartActivityRecord = r;

    if (r.appTimeTracker == null && sourceRecord != null) {
        // If the caller didn't specify an explicit time tracker, we want to continue
        // tracking under any it has.
        r.appTimeTracker = sourceRecord.appTimeTracker;
    }
    // 还记得,在此前startHomeActivity函数中通过TaskDisplayArea初始化的一个ActivityStack么?
    // 此处会获取该对象
    final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();

    // ...... 功能无关代码,此处省略
    // 设置ATMS的mDidAppSwitch参数为true
    mService.onStartActivitySetDidAppSwitch();
    // 控制已经等待Activity的启动,此处为空,自然直接跳出
    mController.doPendingActivityLaunches(false);
    // 最终调用此处的startActivityUnchecked函数
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
            request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
            restrictedBgActivity, intentGrants);

    if (request.outActivity != null) {
        // 设置request的返回ActivityRecord对象
        request.outActivity[0] = mLastStartActivityRecord;
    }
    return mLastStartActivityResult;
}

可以看到,此处启动Activity对象主要会调用startActivityUnchecked函数

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    int result = START_CANCELED;
    final ActivityStack startedActivityStack;
    try {
        mService.deferWindowLayout();
        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
        // 调用startActivityInner函数
        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
        // 返回调用堆栈
        startedActivityStack = handleStartResult(r, result);
        mService.continueWindowLayout();
    }
    // ...... 功能无关代码省略
    return result;
}
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,
        boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    // 设置ActivityStarter初始化状态    
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor, restrictedBgActivity);
    // 获取本次Activity启动的flags
    computeLaunchingTaskFlags();
    
    computeSourceStack();
    // 设置对应的启动flags
    mIntent.setFlags(mLaunchFlags);
    // 从代码和打印日志中可以分析,此处会返回一个null
    final Task reusedTask = getReusableTask();

    // ......

    // Compute if there is an existing task that should be used for.
    // 返回null
    final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
    final boolean newTask = targetTask == null;
    mTargetTask = targetTask;
    // 获取对应参数
    computeLaunchParams(r, sourceRecord, targetTask);

    // ......
    // 返回null,有兴趣可以自行分析
    final ActivityRecord targetTaskTop = newTask
            ? null : targetTask.getTopNonFinishingActivity();
    if (targetTaskTop != null) {
        // ......
    } else {
        mAddingToTask = true;
    }

    // If the activity being launched is the same as the one currently at the top, then
    // we need to check if it should only be launched once.
    // 获取此前创建的ActivityStack
    final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
    if (topStack != null) {
        startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants);
        if (startResult != START_SUCCESS) {
            return startResult;
        }
    }

    if (mTargetStack == null) {
        // 获取TargetStack,这边主要是新建一个ActivityStack,然后将其添加到对应的TaskDisplayArea中
        mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
    }
    // ......

    mRootWindowContainer.sendPowerHintForLaunchStartIfNeeded(
            false /* forceSend */, mStartActivity);
    // 通过ActivityStack的startActivityLocked函数调用,将对应的ActivityRecord添加到对应的ActivityStack
    mTargetStack.startActivityLocked(mStartActivity,
            topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
            mKeepCurTransition, mOptions);
    // true
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isTopActivityFocusable()
                || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                && mStartActivity != topTaskActivity)) {
            // ....... if语句无法进入,代码省略
        } else {
            // If the target stack was not previously focusable (previous top running activity
            // on that stack was not visible) then any prior calls to move the stack to the
            // will not update the focused stack.  If starting the new activity now allows the
            // task stack to be focusable, then ensure that we now update the focused stack
            // accordingly.
            if (mTargetStack.isTopActivityFocusable()
                    && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityInner");
            }
            // 通过获取ActivityStack对象mTargetStack中的ActivityRecord对象
            mRootWindowContainer.resumeFocusedStacksTopActivities(
                    mTargetStack, mStartActivity, mOptions);
        }
    }
    mRootWindowContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);

    // 更新Recents Tasks
    // Update the recent tasks list immediately when the activity starts
    mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(),
            mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetStack);

    return START_SUCCESS;
}

从上述代码中可以看到,这边主要是做了

  1. 通过ActivityStack的startActivityLocked函数调用,将对应的ActivityRecord添加到对应的ActivityStack,这边可以分析下代码,主要同时
  2. 此后通过RootWindowContainer的resumeFocusedStacksTopActivities函数,从ActivityStack中获取对应的Activity并启动

总结

从本篇中分析的代码可知,在Launcher应用的启动过程中,会

  1. 初始化一个包含启动Activity信息的ActivityRecord对象
  2. 初始化一个ActivityStack,用作存放启动Activity的堆栈
  3. 然后将上述的保存Activity信息的ActivityRecord对象存放到ActivityStack堆栈
  4. 通过RootWindowContainner对象的resumeFocusedStacksTopActivities函数启动对应的Activity