启动

287 阅读3分钟

前置流程

应用调用 startActivity,通过 ContextImpl,再经过 Instrumentation,再经过驱动到 AMS。AMS 经一系统处理后到 ActivityStarter#execute()。下面的分析从这里开始:

ActivityStarter

execute

一个是根据 Intent 解析出 ActivityInfo,另一个调用 executeRequest() 继续请求,最后返回处理结果 (setResult 的结果)

int execute() {
    try {
        // 解析 ActivityInfo
        if (mRequest.activityInfo == null) {
            mRequest.resolveActivity(mSupervisor);
        }

        int res;
        synchronized (mService.mGlobalLock) {
            
            // 处理重量级,不懂
            res = resolveToHeavyWeightSwitcherIfNeeded();
            if (res != START_SUCCESS) {
                return res;
            }
            // 下一步
            res = executeRequest(mRequest);
            // WaitResult.
            return getExternalResult(mRequest.waitResult == null ? res
                    : waitForResult(res, mLastStartActivityRecord));
        }
    } finally {
        onExecutionComplete();
    }
}

executeRequest

第一步,判断调用进程是否存在,不存在就报错,整个启动过程终止。

WindowProcessController callerApp = null;

// caller 是 IApplicationThread 类型
// 指调用者进程的 ApplicatonThread 
if (caller != null) {
    callerApp = mService.getProcessController(caller);
    if (callerApp != null) {
        callingPid = callerApp.getPid();
        callingUid = callerApp.mInfo.uid;
    } else {
        err = ActivityManager.START_PERMISSION_DENIED;
    }
}

第二步:处理 Intent 中 FLAG_ACTIVITY_FORWARD_RESULT 标识

// sourceRecord 指源 Activity 对应的 ActivityRecord
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {
    sourceRecord = mRootWindowContainer.isInAnyStack(resultTo);

    if (sourceRecord != null) {
        // 正常情况下,resultRecord 就是 sourceRecord
        if (requestCode >= 0 && !sourceRecord.finishing) {
            resultRecord = sourceRecord;
        }
    }
}
final int launchFlags = intent.getFlags();
// 如果设置过 FLAG_ACTIVITY_FORWARD_RESULT,resultRecord 与 sourceRecord 就不一样了
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
    // 设置 FLAG_ACTIVITY_FORWARD_RESULT 标志时,不能使用 startActivityForResult
    if (requestCode >= 0) {
        SafeActivityOptions.abort(options);
        return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
    }
    resultRecord = sourceRecord.resultTo;
    if (resultRecord != null && !resultRecord.isInStackLocked()) {
        resultRecord = null;
    }
    resultWho = sourceRecord.resultWho;
    requestCode = sourceRecord.requestCode;
    sourceRecord.resultTo = null;
}

第三步各种权限判断,省略。

第四步为目标 Activity 创建 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);
        
mLastStartActivityRecord = r;

第五步调用 startActivityUnchecked() 并将结果返回

mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
        request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
        restrictedBgActivity, intentGrants);
return mLastStartActivityResult;

startActivityUnchecked

result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
        startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
// 有时间再看,直接跟主流程
startedActivityStack = handleStartResult(r, result);
postStartActivityProcessing(r, result, startedActivityStack);
return result;

startActivityInner

参数非常多,有用的没几个:

// r 就是上面创建的目标 Act 对应的 ActivityRecord
// sourceRecord 启动者对应的 ActivityRecord
// startFlags = 0, doResume = true
// 其余的参数全是 null,包括 inTask
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags /*0*/, boolean doResume/*true*/, ActivityOptions options, Task inTask,
        boolean restrictedBgActivity/*false*/, NeededUriGrants intentGrants) {

第一步:将参数记成全局变量,处理了一堆的 flag。挑几个:

mStartActivity = r; // 目标 ActivityRecord
mIntent = r.intent; // 启动目标对应的 Intent
mLaunchMode = r.launchMode; // 目标的启动模式
mLaunchFlags = mIntent.getFlags(); // 本是一个方法,但一般情况下就是 mIntent.getFlags()
mDoResume = doResume // true

// new_task flag 与 startActForResult 无法同时使用
sendNewTaskResultRequestIfNeeded();

// 主要影响 Activity#onUserLeaveHint() 的调用
// 设置了 FLAG_ACTIVITY_NO_USER_ACTION flag,则 mUserLeaving = false
// 没设置,mUserLeaving = true
mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;

// 设置了 FLAG_ACTIVITY_PREVIOUS_IS_TOP,则 mNotTop = sourceRecord,否则为 null
mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? sourceRecord : null;

// 是否设置过 FLAG_ACTIVITY_NO_ANIMATION。设置过为 true,否则为 false
mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;

第二步:处理启动模式 singleInstance 与 singleTop,将模式转换成 intent 中的 flag

  1. 如果有 singleInstance(无论是源 act 还是目标 act),flag 都会加上 FLAG_ACTIVITY_NEW_TASK
  2. 如果目标有 singleTask,也会加上 FLAG_ACTIVITY_NEW_TASK。这就是 singleTask 会按 taskAffinity 去寻找 task 寄存的原因

代码中只挑了一般情况下的逻辑

if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {
    // 源 Act 是 singleInstance
    mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
} else if (isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
    // 目标 Act 是 singleIns 或 singleTask
    mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;
}

第三,寻找源 Act 对应的 task:

if (!mSourceRecord.finishing) {
    // mSourceStack 是 ActivityStack 类型,继承于 Task,先记着后面懂了再说
    // 有啥区别,不清楚。ams 里面名字乱的一逼
    mSourceStack = mSourceRecord.getRootTask();
    return;
}

第四步,寻找是否有现在的的 task 可复用。只有两种情况下才有可能复用:

  • startActivity() 一个 singleInstance 或 singleTask,
  • startActivity() 一个标准/singleTop 的 Activity,但设置有 new_task flag

像平时普通的 startActivity 一个标准启动的 Act 或者使用 startActivityForResult(),是肯定没有可复用的

final Task reusedTask = getReusableTask();
// 方法展开

// FLAG_ACTIVITY_MULTIPLE_TASK 忽略
// 这个结论就是:有 new_task 或者 singleIns 或 singleTask 时为 true
boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
        (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
        || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
        
// 这里是 startActivityForResult 时为 false
putIntoExistingTask &= mInTask == null && mStartActivity.resultTo == null;

// 两个条件综合着看就是上面总结的
if (putIntoExistingTask) {
    // 为 intentActivity 赋值,有可能为 null
}

return intentActivity != null ? intentActivity.getTask() : null;