前置流程
应用调用 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
- 如果有 singleInstance(无论是源 act 还是目标 act),flag 都会加上 FLAG_ACTIVITY_NEW_TASK
- 如果目标有 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;