本章直接从UserController的方法moveUserToForeground讲起,就分析多用户切换的时候,如何启动的新用户里面的那个应用。
此方法进行了一个判断,该判断最终走向两个分支方法:
startHomeActivity和stackSupervisorResumeFocusedStackTopActivity。
什么意思呢,就是说切换用户的是,启动用户有两种情况:
前者是启动默认应用,默认应用一般是开机向导或者桌面,如果首次进入则是开机向导,如果已经设置过开机向导则走桌面。
后者是之前切换到这个用户,并且在这个用户使用了应用,并且在该应用使用过程中切换了用户(用过systemUI状态栏就可以办到)。这种常见切回用户,则可以切回到离开时候的用户。
而判断的方法就是判断后者是否存在。
也就是说:
当我们在某个应用使用过程中,切换用户,我们会把当前应用信息存在stack(类似任务栈)中。
而后在切换回本用户的时候,通过stackSupervisorSwitchUser方法判断该栈有没有内容。
如果有内容则通过stackSupervisorResumeFocusedStackTopActivity方法来resume(恢复状态)之前存在stack的应用。
如果没有内容则通过startHomeActivity方法启动默认应用
rivate void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
boolean homeInFront = mInjector.stackSupervisorSwitchUser(newUserId, uss);
if (homeInFront) {
mInjector.startHomeActivity(newUserId, "moveUserToForeground");
} else {
mInjector.stackSupervisorResumeFocusedStackTopActivity();
}
EventLogTags.writeAmSwitchUser(newUserId);
sendUserSwitchBroadcasts(oldUserId, newUserId);
}
首先是恢复方案:
protected void stackSupervisorResumeFocusedStackTopActivity() {
synchronized (mService) {
mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
}
根据此方法,是调用ActivityStackSupervisor.java里面的resumeFocusedStackTopActivityLocked方法。
从这里看到传入参数均为空。
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
//进行基础判断,是否做好恢复之前应用的准备
if (!readyToResume()) {
return false;
}
//targetStack传入就是null,因此不进入此分支
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOp