首页 技术 正文
技术 2022年11月10日
0 收藏 832 点赞 4,594 浏览 10755 个字

上文写完之后,感觉这个部分写的还是不清晰,本文继续补充一下.

首先还是看堆栈.

obtain:78, PauseActivityItem (android.app.servertransaction)
startPausingLocked:1110, ActivityStack (com.android.server.wm)
pauseBackStacks:1200, TaskDisplayArea (com.android.server.wm)
resumeTopActivityInnerLocked:1662, ActivityStack (com.android.server.wm)
resumeTopActivityUncheckedLocked:1511, ActivityStack (com.android.server.wm)
resumeFocusedStacksTopActivities:2299, RootWindowContainer (com.android.server.wm)
startActivityInner:1731, ActivityStarter (com.android.server.wm)
startActivityUnchecked:1521, ActivityStarter (com.android.server.wm)
executeRequest:1186, ActivityStarter (com.android.server.wm)
execute:669, ActivityStarter (com.android.server.wm)
startActivityAsUser:1100, ActivityTaskManagerService (com.android.server.wm)
startActivityAsUser:1072, ActivityTaskManagerService (com.android.server.wm)
startActivity:1047, ActivityTaskManagerService (com.android.server.wm)

我们一步步分析一下.

startActivity:1047, ActivityTaskManagerService (com.android.server.wm)

    public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}

简单的转发而已

startActivityAsUser:1072, ActivityTaskManagerService

private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
...
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
  1. getActivityStartController() 获取了ATMS的mActivityStartController,该对象在ATMS的initialize中创建.
  2. obtainStarter(intent, "startActivityAsUser") :获取一个ActivityStarter对象.
  3. set*: 类似于Builder模式,给ActivityStarter的相关变量赋值.
  4. execute() :执行ActivityStarter

execute:669, ActivityStarter

int execute() {
try { ...
if (mRequest.activityInfo == null) {
mRequest.resolveActivity(mSupervisor);
} int res;
synchronized (mService.mGlobalLock) {
final boolean globalConfigWillChange = mRequest.globalConfig != null
&& mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
if (stack != null) {
stack.mConfigWillChange = globalConfigWillChange;
}
if (DEBUG_CONFIGURATION) {
Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = "
+ globalConfigWillChange);
} final long origId = Binder.clearCallingIdentity(); res = resolveToHeavyWeightSwitcherIfNeeded();
if (res != START_SUCCESS) {
return res;
}
res = executeRequest(mRequest); Binder.restoreCallingIdentity(origId); if (globalConfigWillChange) {
// If the caller also wants to switch to a new configuration, do so now.
// This allows a clean switch, as we are waiting for the current activity
// to pause (so we will not destroy it), and have not yet started the
// next activity.
mService.mAmInternal.enforceCallingPermission(
android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
if (stack != null) {
stack.mConfigWillChange = false;
}
if (DEBUG_CONFIGURATION) {
Slog.v(TAG_CONFIGURATION,
"Updating to new configuration after starting activity.");
}
mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
} // Notify ActivityMetricsLogger that the activity has launched.
// ActivityMetricsLogger will then wait for the windows to be drawn and populate
// WaitResult.
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
mLastStartActivityRecord);
return getExternalResult(mRequest.waitResult == null ? res
: waitForResult(res, mLastStartActivityRecord));
}
} finally {
onExecutionComplete();
}
}
  1. 如果mRequest.activityInfo为空,就需要调用mRequest.resolveActivity(mSupervisor);去获取.
  2. 查看config是否有变更,普通启动一般没有,先跳过.
  3. resolveToHeavyWeightSwitcherIfNeeded: 暂不清楚是干嘛的.
  4. res = executeRequest(mRequest); :调用executeRequest执行后续操作.

executeRequest:1186, ActivityStarter

private int executeRequest(Request request) {
...
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; final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack(); mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants); if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
} return mLastStartActivityResult;
}
  1. 这里首先做了一系列的判断,新Activity是否合法,是否可以启动它.不可以的话则直接返回了.
  2. 新建了一个ActivityRecord对象.它是Activity在ATMS的一个映射.此时Acitivity进程还没有新建Activity对象,所以此时他们还是不对应的.
  3. 调用startActivityUnchecked

startActivityUnchecked:1521, ActivityStarter

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) { ...
try {
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
} finally {
startedActivityStack = handleStartResult(r, result);
}
...
return result;
}

这里简单的转发一下.

startActivityInner:1731, ActivityStarter

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
...
computeSourceStack();
final Task reusedTask = getReusableTask(); // Compute if there is an existing task that should be used for.
final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
final boolean newTask = targetTask == null;
mTargetTask = targetTask;
// Check if starting activity on given task or on a new task is allowed.
int startResult = isAllowedToStart(r, newTask, targetTask);
if (startResult != START_SUCCESS) {
return startResult;
} final ActivityRecord targetTaskTop = newTask
? null : targetTask.getTopNonFinishingActivity();
if (targetTaskTop != null) {
// Recycle the target task for this launch.
startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
} 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.
final ActivityStack topStack = mRootWindowContainer.getTopDisplayFocusedStack();
if (topStack != null) {
startResult = deliverToCurrentTopIfNeeded(topStack, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
} if (mTargetStack == null) {
mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
if (newTask) {
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
setNewTask(taskToAffiliate);
if (mService.getLockTaskController().isLockTaskModeViolation(
mStartActivity.getTask())) {
Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
} else if (mAddingToTask) {
addOrReparentStartingActivity(targetTask, "adding to task");
} if (!mAvoidMoveToFront && mDoResume) {
mTargetStack.getStack().moveToFront("reuseOrNewTask", targetTask);
if (mOptions != null) {
if (mOptions.getTaskAlwaysOnTop()) {
mTargetStack.setAlwaysOnTop(true);
}
}
if (!mTargetStack.isTopStackInDisplayArea() && mService.mInternal.isDreaming()) {
// Launching underneath dream activity (fullscreen, always-on-top). Run the launch-
// -behind transition so the Activity gets created and starts in visible state.
mLaunchTaskBehind = true;
r.mLaunchTaskBehind = true;
}
} if (newTask) {
EventLogTags.writeWmCreateTask(mStartActivity.mUserId,
mStartActivity.getTask().mTaskId);
} mTargetStack.mLastPausedActivity = null; mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
newTask, mKeepCurTransition, mOptions);
...
return START_SUCCESS;
}

这里首先是计算新的Activity启动所在的堆栈mTargetStack,然后调用mTargetStack.startActivityLocked去启动Activity.

  1. final Task reusedTask = getReusableTask(); 首先查看现有的任务中是否有可以重复使用的任务.
  2. 如果没有找到reusedTask,那么调用computeTargetTask 看看能否找到一个task存放这个Activity.如果都不存在的话,那么就要新建一个Task了.
  3. 我们是从Launcher新启动一个Activity,并且这个Activity没有启动过.一般情况下这里就会新建一个Task,并且新建一个Stack.并把当前待启动的ActivityRecord对象放到这个Stack顶.

resumeFocusedStacksTopActivities:2299, RootWindowContainer

 boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
boolean result = false;
if (targetStack != null && (targetStack.isTopStackInDisplayArea()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
...
}

这里也是很简单的就转给相应的Stack去处理.

resumeTopActivityUncheckedLocked:1511, ActivityStack

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
...
} finally {
mInResumeTopActivity = false;
}
...
}

转发给Lock函数处理.

resumeTopActivityInnerLocked:1666, ActivityStack

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
}
  1. 前面省略的逻辑中有一部分是判断当前是否有Acitivity正在执行pause操作,是的话这里就直接返回了.
  2. 如果不是的话,则先pause当前显示区域的后台堆栈中的resumed状态的Activity,然后pause当前栈的resumed Activity.

startPausingLocked:1110, ActivityStack

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming) {
...
if (prev.attachedToProcess()) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving); mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
}

这里的prev对应的就是当前栈中的mResumedActivity,如果当前它还是attach到进程上的,那么这里就调用scheduleTransaction给他传递了一个pause操作

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,489
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,904
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,737
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,490
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,128
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,291