Android启动过程(三)ActivityManagerService----1 继续上一篇
Step3@startActivityLocked(1),如果此时还没有找到合适的目标Activity来处理Intent,或者这个目标的ActivityInfo为空,都说明这个Intent 没有办法继续处理了,因此程序会直接报错返回。
Step4@startActivityLocked(1),上面的判断通过后,还需要检查调用者是否有权限来启动指定的Activity。具体如下所示
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
final int startAnyPerm = mService.checkPermission(
START_ANY_ACTIVITY, callingPid, callingUid);
final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
callingUid, aInfo.applicationInfo.uid, aInfo.exported);
上述这两个权限检查必须全部通过,否则会抛出SecurityException。
Step5@startActivityLocked(1),生成一个ActivityRecord变量r,记录当前的各项判断结果,然后进一步调用startActivityUncheckedLocked----这个函数将涉及一系列启动模式和Intent 标志的处理,建议读者穿插阅读ActivityTask小节中对这些标志的说明。
接下来我们再详细讲解startActivityUnCheckedLocked这个函数。
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
final int startActivityUncheckedLocked(ActivityRecord r,
ActivityRecord sourceRecord, int startFlags, boolean doResume,
Bundle options) {
//...
//此时launcheFlags为0
int launchFlags = intent.getFlags();
//notTop为null
ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
!= 0 ? r : null;
//默认情况下startFlags不会设置START_FLAG_ONLY_IF_NEEDED
if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
//...这里的代码不会执行
}
//r.launchMode = ActivityInfo.LAUNCH_SINGLE_TASK
if (sourceRecord == null) {
//这里的代码不会执行
} else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
//这里的代码不会执行
} else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
}
//此时r.resultTo!=null launchFlags设置了Intent.FLAG_ACTIVITY_NEW_TASK
if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
//...
r.resultTo = null;
}
//addingToTask如果为true表示正在添加至某个task,后续需要将r添加至sourceRecord所在的task
boolean addingToTask = false;
//movedHome表示是否移动home task
boolean movedHome = false;
TaskRecord reuseTask = null;
if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
(launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
//此时 r.resultTo = null
if (r.resultTo == null) {
//此时找到的taskTop是Activity A的ActivityRecord,
//因为Actvity B和A的ActivityRecord所在的Task是相关的
ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
? findTaskLocked(intent, r.info)
: findActivityLocked(intent, r.info);
//找到了相关task
if (taskTop != null) {
//重设task的intent
if (taskTop.task.intent == null) {
//...
}
//此时找到的task已在栈顶
ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop);
if (curTop != null && curTop.task != taskTop.task) {
//... 这里的代码不会执行
}
//launchFlags为0
if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
taskTop = resetTaskIfNeededLocked(taskTop, r);
}
//... 一般情况下startFlags 不会设置 START_FLAG_ONLY_IF_NEEDED
if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
//...
}
// ==================== begin
// launchFlags此时为0
if ((launchFlags &
(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK))
== (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) {
//...这里的代码不执行
} else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
|| r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
// r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
// 故此会进入该分支
//因为B还从未启动,故此得到的top为null
ActivityRecord top = performClearTaskLocked(
taskTop.task.taskId, r, launchFlags);
if (top != null) {
//...这里的代码不执行
} else {
addingToTask = true;
sourceRecord = taskTop;
}
} else if (r.realActivity.equals(taskTop.task.realActivity)) {
//...这里的代码不执行
} else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
//...这里的代码不执行
} else if (!taskTop.task.rootWasReset) {
//...这里的代码不执行
}
// ==================== end
// 此时 addingToTask为true
if (!addingToTask && reuseTask == null) {
//...这里的代码不执行
}
}
}
}
//...
if (r.packageName != null) {
ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
if (top != null && r.resultTo == null) {
//此时task还没有B的ActivityRecord,故此不会进入下述分支
if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
//...这里的代码不执行
}
}
} else {
//...这里的代码不执行
}
boolean newTask = false;
boolean keepCurTransition = false;
// 此时 r.resultTo == null addingToTask为true sourceRecord != null
if (r.resultTo == null && !addingToTask
&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
//...这里的代码不执行
} else if (sourceRecord != null) {
if (!addingToTask &&
(launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
//...这里的代码不执行
} else if (!addingToTask &&
(launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
//...这里的代码不执行
}
//将B的ActivityRecord加入A的ActivityRecord所在的Task里
r.setTask(sourceRecord.task, sourceRecord.thumbHolder, false);
//...
} else {
//...这里的代码不执行
}
//...
startActivityLocked(r, newTask, doResume, keepCurTransition, options);
return ActivityManager.START_SUCCESS;
}
Step1@startActivityUnCheckedLocked,前期准备
int launchFlags = intent.getFlags();
然后处理FLAG_ACTIVITY_NO_USER_ACTION.。这个标志表示并不是用户“主观意愿”启动的Activity,而是如来电,闹钟事件等触发的Activity启动。
mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
if (DEBUG_USER_LEAVING) Slog.v(TAG, "startActivity() => mUserLeaving=" + mUserLeaving);
如果调用者指示先不要resume(doResume为空),那么我们将delayedResume设置为true。如果使用了FLAG_ACTIVITY_PREVIOUS_IS_TOP,则notTop为r本身,否则为空。
Step2@startActivityUnCheckedLocked,STRAT_FLAG_ONLY_IF_NEEDED
只在需要的情况下才启动目标,即如果被启动的对象和调用者是同一个,那么就没有必要重复操作。
Step3@startActivityUnCheckedLocked,判断是否要启动新的Task
变量launchFlags是用于记录Activity的启动方式的。如果sourceRecord为空,表明我们应该启动一个新的task来容纳目标Activity,因而需要设置FLAG_ACTIVITY_INSTANCE,或者目标ActivityRecord的(launcherMode是在AndroidManifest中设置的),也需要在新的Task中启动
Step4@startActivityUnCheckedLocked,在启动新Task的情况下无法返回结果值
如果上一步骤判断的结果是需要启动一个新的Task,那么目标Activity就和原先的调用者不在一个Task中了。由于startActivity的结果是没有办法跨越Task传递的,这时我们返回一个RESULT_CANCELED。
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(-1,
resultRecord, resultWho, requestCode,
Activity.RESULT_CANCELED, null);
}
}
Step5@startActivityUnCheckedLocked. 对于新Task的细化处理
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, this, container, options);
如果不是FLAG_ACTIVITY_INSTANCE,那么我们调用findTaskLocked 来找到符合要求的Task---此Task的最顶端就是我们要找的目标Activity一个实例。这两个函数,即findTaskLocked和finishActivityLocked都有可能返回空。
如果用户设置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,那么执行resetTaskIfNeedLocked来清理Task。如果START_FLAG_ONLY_IF_NEEDED不为空,那么有两种可能:要么resume顶部的Activity(doResume不为空);要么abort。
如果标志FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLWAR_TASK同时存在,那么我们清理整个Task(performClearTaskLocked);否则如果FLAG_ACTIVITY_CLEAR_TOP或者launcherMode为singleTask(或singleInstance),那么就清理目标Activity以上的那些元素;否则如果Task中最顶层Activity就是目标对象,那么我们把整个Task提到前台;否则如果设置了标志FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,那么我们将目标对象加入Task顶端。
假如当前Task最顶端的Activity与我们的目标对象时同一个,那么我们需要确认整个目标是否只能启动一次。
Step6@startActivityUnCheckedLocked.接下来的代码是基于newTask为false的情况,不过也有例外。比如设置了FLAG_ACTIVITY_NEW_TASK,但是经过前面的判断后addingToTask为false,此时newTask还是为真。
Step7@startActivityUnCheckedLocked。最后调用startActivity(2)来真正的执行启动操作。这个函数不仅是AMS启动Activity的关键,同时也是Activity后续能否在WMS中得到正常处理的关键。
函数startActivity(2)是启动Activity的最后一站,主要包含以下几方面的工作。
Step1@startActivityLocked(2)。首先,如果目标Activity不是在新task中启动的,即newTask变量为false,那么程序要找出目标Activity位于哪个老Task中(这可以通过遍历整个mHistory列表来实现)。找到后,如果这个Task当前对用户还不是可见的,那么只需要将它加入mHistory,并在WMS中做好注册,但不启动它。
Step2@startActivityLocked(2)。将这个Activity放在stack的最顶层,这样才能与用户交互。
Step3@startActivityLocked(2),接下来如果不是AMS中的第一个Activity,则执行切换动画(不过这也要取决于FLAG_ACTIVITY_NO_ANIMATION标志)。执行的动画类型分为WindowManagerPolicy.TRANSIT_OPEN(如果是启动新的Task)及WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN(不启动新的Task)两种。
Step4@startActivityLocked(2),一个Activity的UI界面为了在终端屏幕上显示出来,很重要的一点就是它在WMS中必须“有档可查”,这个“档”就是appToken,它是在startActivity中添加的。
Step5@startActivityLocked(2).Activity是有affinity的----言下之意,就是它们“更亲近”与某些affinity相符的task。因而如果启动了一个新的task,就需要检查是否存在“同兴趣”的其他Activity。另外,如果用户使用了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,就满足“NEEDED”条件了,因而需要调用resetTaskIfNeededLocked。
Step6@startActivityLocked(2).调用resumeTopActivityLocked.确保被调用的Activity所在的栈处于顶端
至此,startActivity函数的一系列处理流程就分析完了---只不过Activity的启动过程还没有结束。一方面,AMS会继续调用resumeTopActivityLocked来恢复最上层的Activity,并pause之前的Activity;另一方面,在Activity切换的过程中还要首先展示切换动画,然后两个新旧Activity还会向WMS分别申请和释放Surface,最终将他们显示/不显示在屏幕上。这些内容会在WMS章节中再详细分析。
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
if (targetStack == null) {
targetStack = getFocusedStack();
}
// Do targetStack first.
boolean result = false;
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (stack == targetStack) {
// Already started above.
continue;
}
if (isFrontStack(stack)) {
stack.resumeTopActivityLocked(null);
}
}
}
return result;
}