Activity的冷启动与生命周期
本文基于android12,13 进行分析
activity冷启动的流程如下几个步骤
- 应用端调用到AMS开启启动流程,构造出ActivityStarter。
- 构造出新的task,并把之前创建的Activity添加至该task。
- 服务端执行pause流程,随后拉其新进程。
- 应用端完成pasue,随后回调到服务端。
- 新进程拉起,执行attach,回调到服务端。
- 对需要启动的activity进行resume。
一、应用端调用到AMS开启启动流程,构造出ActivityStarter
该阶段主要做了三件事:
1. 接收应用端启动activit的请求,检查参数是否合法,然后根据参数构造出用来启动activity的ActivityStarter,然后执行该ActivityStater的execute方法.
2. 检查是否有启动activity的权限,没有则终止。然后根据intent构造出新启动Activity对应的ActovotyRecord对象。
如下:
1. 接收应用端启动activity的请求,检查参数是否合法,然后根据参数构造出用来启动activity的ActivityStarter
ActivityTaskManagerService.java
如下在接收都服务端的启动activity请求后,补全参数后,根据参数构造出一个ActivityStater,随后执行他的execute方法:
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
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) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
SdkSandboxManagerLocal.class);
if (sdkSandboxManagerLocal == null) {
throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
+ " an activity from an SDK sandbox uid.");
}
sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
}
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
补全参数后,根据参数构造出一个ActivityStater。并执行ActivityStarter的execute方法
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();
}
2. 检查是否有启动activity的权限,没有则终止
如下经检查是否具有启动activity的权限,没有则终止。随后构造出一个需要启动Activity对应的的ActivityRecord。
ActivityStater.java
// 正如注释里面所描述的,启动activity的流程在这里开始,这里将开始进行几轮权限检查
/**
* Executing activity start request and starts the journey of starting an activity. Here
* begins with performing several preliminary checks. The normally activity launch flow will
* go through {@link #startActivityUnchecked} to {@link #startActivityInner}.
*/
private int executeRequest(Request request) {
前面进行权限检查的代码非常的长.省略
// app [on install success].
if (rInfo != null && rInfo.auxiliaryInfo != null) {
intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
resolvedType = null;
callingUid = realCallingUid;
callingPid = realCallingPid;
// The ephemeral installer shouldn't get any permission grants
// intended for the original destination
intentGrants = null;
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
}
// TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
// Pending intent launched from systemui also depends on caller app
if (callerApp == null && realCallingPid > 0) {
final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
if (wpc != null) {
callerApp = wpc;
}
}
//在这里构造出新的ActivityRecord
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
mLastStartActivityRecord = r;
if (r.appTimeTracker == null && sourceRecord != null) {
// If the caller didn't specify an explicit time tracker, we want to continue
// tracking under any it has.
r.appTimeTracker = sourceRecord.appTimeTracker;
}
// Only allow app switching to be resumed if activity is not a restricted background
// activity and target app is not home process, otherwise any background activity
// started in background task can stop home button protection mode.
// As the targeted app is not a home process and we don't need to wait for the 2nd
// activity to be started to resume app switching, we can just enable app switching
// directly.
WindowProcessController homeProcess = mService.mHomeProcess;
boolean isHomeProcess = homeProcess != null
&& aInfo.applicationInfo.uid == homeProcess.mUid;
if (!restrictedBgActivity && !isHomeProcess) {
mService.resumeAppSwitches();
}
// 权限检查通过,进一步启动
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, restrictedBgActivity, intentGrants);
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
......
try {
mService.deferWindowLayout();
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
// 在这里进一步启动
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
startedActivityRootTask = handleStartResult(r, options, result, newTransition,
remoteTransition);
mService.continueWindowLayout();
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
}
二、构造出新的task,并把之前创建的Activity添加至该task
上文中执行了ActivityStater的方法后,会进入到ActivityStater的executeRequest方法中,这个方法非常的长,因为要对传进来启动参数做检查,参数有问题则终止,初次之外还要检查有没有启动目标Activity的权限,没有权限则终止。
在ActivityStater的startActivityInner中主要进行过了如下的步骤:
- 计算出需要启动的activity 放到那和Task中,冷启动的话targetTask为null, newTask 为true
- 新建的Task,同时把之前创建出来的ActivityRecord添加到新建的task中。
- 处理启动窗口和过渡窗口。
- 继续进入到RootWindowContainer继续启动流程。
- 更新recent栈 的信息。
ActivityStater.java
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
// 初始化ActivityStater
setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
voiceSession, voiceInteractor, restrictedBgActivity);
...
// 从当前已经存在的Task中,根据新建activity的配置信息,找到合适的的task并返回.没有找到合适的就返回null
final Task reusedTask = getReusableTask();
...
// 计算出需要启动的activity 放到那和Task中,冷启动的话targetTask为null, newTask 为true
// 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;
...
// 新建的Task走到这里。
if (mTargetRootTask == null) {
mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
mOptions);
}
if (newTask) {
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// 新建Task的, 这里会把之前创建的ActivityRecord添加到新建的Task中,eventlog打印
//Starting new activity %s in new task %s
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
addOrReparentStartingActivity(targetTask, "adding to task");
}
// 把新建的task移动到DisplayArea顶部
if (!mAvoidMoveToFront && mDoResume) {
mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
&& !dreamStopping) {
// 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) {
// wm_create_task event log打印
EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
}
...
// 处理启动窗口,过度动画等、
mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
mOptions, sourceRecord);
if (mDoResume) {
final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
if (!mTargetRootTask.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
// Passing {@code null} as the start parameter ensures all activities are made
// visible.
mTargetRootTask.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mTargetRootTask.mDisplayContent.executeAppTransition();
} else {
if (mTargetRootTask.isTopActivityFocusable()
&& !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
mTargetRootTask.moveToFront("startActivityInner");
}
// 继续启动流程
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
}
...
// 更新最近任务栈的信息,
mSupervisor.mRecentTasks.add(startedTask);
三、服务端执行pause流程,随后拉其新进程
1.流程追踪
这里的主要思想是:在启动之前要先对目标屏幕上的已经resume的Activity进行pause,displayArear出发,找到各个叶子节点的Task,对Task中处于resume状态的Activity进行pause处理,顺道新建需要启动actiivty的进程。
进入到RootWindowContainer:
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
if (!mTaskSupervisor.readyToResume()) {
return false;
}
boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
// 继续启动流程,
// target 带启动的ActiivtyRecord,deferPause:是否延后pause,一般为false
// 这里的targetRootTask就是我们刚才新建的Task
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
...
}
接下来会进入到Task的resumeTopActivityUncheckedLocked方法中。
该方法中会遍历,从顶部置Task的叶子节点,直至遍历到叶子节点上才开始进行下一步,否则不断调用Task的resumeTopActivityUncheckedLocked方法进行遍历,这是因为有的Task中的child并不是ActivtyRecord类型,可能是Task类型,只要叶子节点上的Task中的child是ActivityRecord类型。在遍历的过程中会经过需要启动的ActivityRecord所在的Task,也就是刚刚新建的Task,执行该Task的resumeTopActivityInnerLocked();
class Task
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean someActivityResumed = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
if (isLeafTask()) {
if (isFocusableAndVisible()) {
// 当前所在的Task就是我们新建的Task,是叶子节点,则进入到下一步,这里prev是要启动的Activity
someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
}
} else {
int idx = mChildren.size() - 1;
// 遍历所有子节点,执行resumeTopActivityUncheckedLocked
while (idx >= 0) {
final Task child = (Task) getChildAt(idx--);
if (!child.isTopActivityFocusable()) {
continue;
}
if (child.getVisibility(null /* starting */)
!= TASK_FRAGMENT_VISIBILITY_VISIBLE) {
break;
}
someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options,
deferPause);
// Doing so in order to prevent IndexOOB since hierarchy might changes while
// resuming activities, for example dismissing split-screen while starting
// non-resizeable activity.
if (idx >= mChildren.size()) {
idx = mChildren.size() - 1;
}
}
}
final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return someActivityResumed;
}
进入到需要pause的Task:
class Task
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
// Not ready yet!
return false;
}
// 获取该task顶部,处于running状态的task.在需要启动的Task中,topActivity就是要需要启动的Activity
final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
if (topActivity == null) {
// There are no activities left in this task, let's look somewhere else.
return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
}
final boolean[] resumed = new boolean[1];
// 获取topActivity的TaskFragment
final TaskFragment topFragment = topActivity.getTaskFragment();
// 进一步走到这里,这里的prev 是要启动的ActivityRecord
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
forAllLeafTaskFragments(f -> {
if (topFragment == f) {
return;
}
if (!f.canBeResumed(null /* starting */)) {
return;
}
// 调用TaskFragment的resumeTopActivity方法
resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
}, true);
return resumed[0];
}
进入到需要启动的ActivityRecord所在的TaskFragment:
在该方法中进行了三个重要的步骤:
- 进入到TaskDisplayArea中,从顶部向下开始遍历各个WindowContain节点,找到处于叶子节点的Task,如果该Task中有处于resume的ActivityRecord,进行pause。
- 对需要启动的Actiivty拉起一个新进程。
- 等待 pause 和 拉起新进程完成,返回。
需要注意的是应用端pause的过程和拉起新进程的是同步进行的,在pauseBackTasks函数中会生成一个pause生命周期的事务然后通过binder发送给需要pause的应用端,随即立刻继续向下执行,执行到AtmService.startProcessAsync()去拉起新进程。而应用端在接收到pause生命周期的事务后开始执行pause。
TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
// next是要启的ActivityRecord
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canResumeByCompat()) {
return false;
}
next.delayedResume = false;
// If we are currently pausing an activity, then don't do anything until that is done.
// allPausedComplete表明该RootWindowContainer所有已经开始pause的activityRecord是否已经完成pause,RootWindowContainer整个层级数的根节点,即allPausedComplete表明的是整个系统中应已经始paused的activityRecord是否完成pause
// 当前的系统中虽然有需要被pause的activityRecord,但还并未开始pasue,故该值为 true
final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
// allPausedComplete 为true,不会就如该分支
if (!allPausedComplete) {
ProtoLog.v(WM_DEBUG_STATES,
"resumeTopActivity: Skip resume: some activity pausing.");
return false;
}
// TaskDisplayArea节点上挂载着对应屏幕上所有的Task
final taskDisplayArea taskDisplayArea = getDisplayArea();
......
// taskDisplayArea.pauseBackTasks(next) 执行当前屏幕对应TaskDisplayArea的pauseBackTasks
// next 为要启动的Activity。当有需要的pasue的ActivityRecord,则pausing为true
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
if (mResumedActivity != null) {
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Pausing %s", mResumedActivity);
pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
next, "resumeTopActivity");
}
// 进入该分支,
if (pausing) {
ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: Skip resume: need to"
+ " start pausing");
// At this point we want to put the upcoming activity's process
// at the top of the LRU list, since we know we will be needing it
// very soon and it would be a waste to let it get killed if it
// happens to be sitting towards the end.
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
true /* activityChange */, false /* updateOomAdj */,
false /* addPendingTopUid */);
// 进入该分支,next需要启动的ActivityRecord,next.isProcessRunning()表示该Activity是否绑定 进程,因为新启动的,则没有绑定进程,则进进入该分支,去拉起进程
} else if (!next.isProcessRunning()) {
// Since the start-process is asynchronous, if we already know the process of next
// activity isn't running, we can start the process earlier to save the time to wait
// for the current activity to be paused.
final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
}
if (lastResumed != null) {
lastResumed.setWillCloseOrEnterPip(true);
}
// 直接返回,现在系统等pasue和拉起进程结束
return true;
} else if (mResumedActivity == next && next.isState(RESUMED) {
.....
}
.....
之后启动流程一分为二,开始pause和拉起新进程,拉起新进程暂且不表,先继续分析pause过程。接下来继续进入到pauseBackTasks进行分析。
在TaskDisplayArea的pauseBackTasks方法中会遍历该TaskDisplayArea的所有的叶子节点,如果该叶子节点有处于resumed的ActivityRecord,则执行该叶子节点的 startPausing方法。 pauseBackTasks的返回true说明该方法的执行过程中触发了activity的pasue
TaskDisplayArea.java
boolean pauseBackTasks(ActivityRecord resuming) {
final int[] someActivityPaused = {0};
// 遍历该TaskDisplayArea的叶子节点
forAllLeafTasks(leafTask -> {
// Check if the direct child resumed activity in the leaf task needed to be paused if
// the leaf task is not a leaf task fragment.
if (!leafTask.isLeafTaskFragment()) {
final ActivityRecord top = topRunningActivity();
final ActivityRecord resumedActivity = leafTask.getResumedActivity();
if (resumedActivity != null && top.getTaskFragment() != leafTask) {
// Pausing the resumed activity because it is occluded by other task fragment.
// 继续进行pause流程,resuming为将要启动的ActivityRecord
if (leafTask.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
someActivityPaused[0]++;
}
}
}
leafTask.forAllLeafTaskFragments((taskFrag) -> {
final ActivityRecord resumedActivity = taskFrag.getResumedActivity();
if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
someActivityPaused[0]++;
}
}
}, true /* traverseTopToBottom */);
}, true /* traverseTopToBottom */);
return someActivityPaused[0] > 0;
}
如下比较关键,因为接下来开始开始生成ClientTransaction来,然后传递给应用端来执行相关的生命周期变化
TaskFragment.java
boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
String reason) {
//prev =mResumedActivity,即已经resumed的ActivityRecord,需要进行pause
ActivityRecord prev = mResumedActivity;
if (prev == resuming) {
Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
return false;
}
.....
// prev是需要进行的paused的ActivityRecord ,自然已经绑定了进程了,进入该分支
if (prev.attachedToProcess()) {
if (shouldAutoPip) {
boolean didAutoPip = mAtmService.enterPictureInPictureMode(
prev, prev.pictureInPictureArgs, false /* fromClient */);
ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
+ "directly: %s, didAutoPip: %b", prev, didAutoPip);
} else {
// 进入到该流程 继续进行pause
schedulePauseActivity(prev, userLeaving, pauseImmediately,
false /* autoEnteringPip */, reason);
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mTaskSupervisor.mNoHistoryActivities.remove(prev);
}
....
TaskFragment.java
void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, boolean autoEnteringPip, String reason) {
ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
try {
EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving, reason);
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(), // 生成了一个PauseActivityItem
prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately, autoEnteringPip));
Slog.d("trace_activity_start", " schedulePauseActivity pasueActivity:" + prev + " call:\n" + Arrays.toString(new Exception().getStackTrace()));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mTaskSupervisor.mNoHistoryActivities.remove(prev);
}
}
ClientLifecycleManager.java
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
@NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
// 把刚才生成的PauseActivityItem 和 一众参数封装到 clientTransaction中
final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
stateRequest);
scheduleTransaction(clientTransaction);
}
2.ATMS通过跨进程的方式使得Activity的生命周期发生转换
上文中在pasue的过程中服务端生成了一个PauseActivityItem,后面把PauseActivityItem封装到ClientTransaction中,随后把这个ClientTransaction发送给应用端执行生命周期转换。
其中个PauseActivityItem派生于ActivityLifecycleItem,类图如下:
可见派生于ActivityLifecycleItem的类有:
- StartActivityItem
- ResumeActivityItem
- PuaseActivityItem
- StopActivityItem
- DestroyActivityItem
public abstract class ActivityLifecycleItem extends ActivityTransactionItem {
// 此方法会返回目标的生命周期状态
@LifecycleState
public abstract int getTargetState();
}
派生于ActivityLifecycleItem的类实现了getTargetState(),返回值便是目标生命周期状态。
同时ActivityLifecycleItem和ClientTransationItem间接或者直接派生于BaseClientRequest,在BaseClientRequest中有三个方法:
public interface BaseClientRequest extends ObjectPoolItem {
// 做执行execute的前置动作
default void preExecute(ClientTransactionHandler client, IBinder token) {
}
// 执行生命周期相关动作
void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions);
// 执行execute的收尾动作
default void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
}
}
在ClientTransaction中有三个字段,分别是:
- mActivityCallbacks (List )
- mLifecycleStateRequest (ActivityLifeCycleitem)
- mClient (保存着应用的一个binder代理)
有两个方法:
- 把ClientTransaction通过mClient发送给应用端
- 应用端执行ClientTransaction的preExcute()
a. 遍历callback执行callback的preExecute()
b. 执行ActivityLifecycleItem的preExecute() - 应用端执行ClientTransaction的execute()
a. 遍历callback执行callback的execute()
b. 遍历callback执行callback的postExecute()
c. 执行ActivityLifecycleItem的execute()
d. 执行ActivityLifecycleItem的postExecute()
生命周期转换一般发生在3.a或3.c阶段,而3.b和3.d阶段一般都是当应用的生命周期转换结束后,通过binder执行一些回调到服务端。代工的流程图如下
ATMS通过跨进程的方式使得Activity的生命周期发生转换的大概流程已经简单介绍了,后面将用pasue和resum举例。
四、应用端完成pasue,随后回调到服务端。
上文可知,服务端在pasue阶段会生成一个包含PasueActivityitem的ClientTransaction,顾该ClientTransaction对象的mLifecycleStateRequest是PasueActivityitem类型,同时在构造ClientTransaction阶段并未给mActivityCallbacks赋值,顾callback为空。
继续跟踪pasue流程。
ClientTransaction经过binder传递给应用端,同时通过scheduleTransaction执行该ClientTransaction
ActivityThread.java
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
如下会会执行ClientTransaction的preExecute(),正如上文所描述,在该方法中会执行callback的preExecute(),和ActivityLifecycleItem的preExecute(),pause的过程中生成ClientTransaction的没有callback,该ClientTransaction中的mLifecycleStateRequest为一个PauseActivityItem,而pasue的preExecute()知识修改了以下进程在虚拟机的状态。
public abstract class ClientTransactionHandler {
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
// 执行ClientTransaction的preExecute(2.)
transaction.preExecute(this);
//将会到ActivityThread的主线称中,调用ClientTransaction的execute()
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
接下来会到TransactionExecutor继续执行ClientTransaction的相关方法,如下:
- 执行callback的execute()和postExecute()
- 执行ActivityLifecycleItem的execute()和postExecute()。
因为callback不存在,所以只关注2.执行ActivityLifecycleItem
TransactionExecutor.java
public void execute(ClientTransaction transaction) {
....
if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
// 遍历callback执行callback的execute()
// 遍历callback执行callback的postExecute()
executeCallbacks(transaction);
// 执行ActivityLifecycleItem的execute()
// 执行ActivityLifecycleItem的postExecute()
executeLifecycleState(transaction);
mPendingActions.clear();
....
}
private void executeLifecycleState(ClientTransaction transaction) {
// 获取ClientTransaction中的ActivityLifecycleItem
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
+ lifecycleItem + " for activity: "
+ getShortActivityName(token, mTransactionHandler));
}
if (r == null) {
// Ignore requests for non-existent client records for now.
return;
}
// Cycle to the state right before the final requested state.
// 计算出当前状态到目标状态的路经,然后依次完成生命周期状态转换,pause不走该流程
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// Execute the final transition with proper parameters.
// 执行lifecycleItem的execute 完成 从onResume到onPause的转换
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
// 执行 lifecycleItem.postExecute 进行pause的一些收尾工作,然后会回调到服务端,告诉服务端该Activity已经完成paused
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
如上,在executeLifecycleState主要作了三件事:
- 通过cycleToPath()
a. 计算出当前状态到目标状态的路径
b. 根据计算出的路径依次执行路径上的生命周期的回调
举个例子:当前状态 create, 目标状态 resume, 那当前的状态到目标状态的路径为 [start,resume],所以依次调用目标activity的onStart()和onResume()方法。
回到咱们的pause流程,当前的状态是resume,目标状态时pause,故路径为[pause],但是代码中cycleToPath()的excludeLastState=true,所以就会跳过最后一个状态,路径列表移除最后一个状态,故路径列表:[pause],移除最后一个就变成空列表,pasue流程在该函数中不会执行相关生命周期回调。
可见:cycleToPath()是一个很重要的过程,故可以这样总结:
-
把ClientTransaction通过mClient发送给应用端
-
应用端执行ClientTransaction的preExcute()
a. 遍历callback执行callback的preExecute()
b. 执行ActivityLifecycleItem的preExecute() -
应用端执行ClientTransaction的execute()
a. 遍历callback执行callback的execute()
b. 遍历callback执行callback的postExecute()
c. cycleToPath()
d. 执行ActivityLifecycleItem的execute()
e. 执行ActivityLifecycleItem的postExecute() -
lifecycleItem.execute(),即执行PauseActivityItem的execute,这个方法中会调用到目标Activity的onPause()方法,如下:
PauseActivityItem.java
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
// r目标的Activity,接下来会调用到Activity的onPaused方法
client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, mAutoEnteringPip,
pendingActions, "PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
- 执行到该方法,就意味这目标Activity的onPause方法已经得到执行,接下来就要向服务端汇报已经完成了pasue:
PauseActivityItem.java
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mDontReport) {
return;
}
// TODO(lifecycler): Use interface callback instead of actual implementation.
// 这里
ActivityClient.getInstance().activityPaused(token);
}
如下在activityPaused方法中将通过binder调用到服务端的ActivityClientController的activityPaused方法,进而向服务端汇,除此之外还可以看到 activityStopped,activityDestroyed之类的方法,这些方法的作用和activityPaused类似。
public class ActivityClient {
/** Reports {@link Activity#onResume()} is done. */
public void activityResumed(IBinder token, boolean handleSplashScreenExit) {
....
}
/** Reports {@link Activity#onPause()} is done. */
public void activityPaused(IBinder token) {
try {
// 会通过binder调用到服务端的ActivityClientController的activityPaused方法
getActivityClientController().activityPaused(token);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
public void activityStopped(IBinder token, Bundle state, PersistableBundle persistentState,
CharSequence description) {
.....
}
public void activityDestroyed(IBinder token) {
.....
}
....
}
接下来,流程回到了服务端,如下:
- 根据应用端的传过来的token找出刚才已经完成paused的Activity对应的ActivityRecord。
- 执行AtivityRecoed的activityPaused()
ActivityClientController.java
class ActivityClientController extends IActivityClientController.Stub {
ActivityClientController(ActivityTaskManagerService service) {
mService = service;
mGlobalLock = service.mGlobalLock;
mTaskSupervisor = service.mTaskSupervisor;
mContext = service.mContext;
}
@Override
public void activityResumed(IBinder token, boolean handleSplashScreenExit) {
......
}
@Override
public void activityTopResumedStateLost() {
......
}
@Override
public void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
// 根据应用端的传过来的token找出刚才已经完成paused的Activity对应的ActivityRecord
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
// pause
// 根据ActivityRecoed的activityPaused
r.activityPaused(false);
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
Binder.restoreCallingIdentity(origId);
}
@Override
public void activityStopped(IBinder token, Bundle icicle, PersistableBundle persistentState,
CharSequence description) {
......
}
@Override
public void activityDestroyed(IBinder token) {
....
}
}
如下将会进一步去resume
void activityPaused(boolean timeout) {
ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", token,
timeout);
final TaskFragment taskFragment = getTaskFragment();
if (taskFragment != null) {
removePauseTimeout();
final ActivityRecord pausingActivity = taskFragment.getPausingActivity();
if (pausingActivity == this) {
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
(timeout ? "(due to timeout)" : " (pause complete)"));
mAtmService.deferWindowLayout();
try {
// 调用刚才已经pauseactivity对应的TaskFragment的completePause,
// 注意这里第一个参数resumeNext为true,这就意味着接下里要去resume Activity了
taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
} finally {
mAtmService.continueWindowLayout();
}
return;
} else {
.....
}
}
.....
}
如下主要完成两件事:
- 通过RootWindowContainer.resumeFocusedTasksTopActivities(),服务端resume需要启动的Activity
- 通过RootWindowContainer.ensureActivitiesVisible(),将会把之前paused的ActivityRecord添加到stoping列表中,为后续的stop的流程做准备(stop流程后续会介绍)
需要注意的是RootWindowContainer.resumeFocusedTasksTopActivities()这个方法之前进入过。在三.1, 该有一点需要注意的是,在调用mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev, null /* targetOptions */);
的时候传递的第一个参数是topRootTask,topRootTask即为当前在最顶部的Task,因为在前面的流程中,新建task的过程中会把新建的Task移动到最顶部,故topRootTask就为新建的那个Task
@VisibleForTesting
void completePause(boolean resumeNext, ActivityRecord resuming) {
// 这里的mPausingActivity就是我们刚才pause的ActivityRecord
ActivityRecord prev = mPausingActivity;
.....
// pause的流程已经完成把mPausingActivity置为null
mPausingActivity = null
// 准备去resume下一个activity
if (resumeNext) {
final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topRootTask != null && !topRootTask.shouldSleepOrShutDownActivities()) {
// 可以看到,又看到我们熟悉的地方
mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev,
null /* targetOptions */);
} else {
// checkReadyForSleep();
final ActivityRecord top =
topRootTask != null ? topRootTask.topRunningActivity() : null;
if (top == null || (prev != null && top != prev)) {
// If there are no more activities available to run, do resume anyway to start
// something. Also if the top activity on the root task is not the just paused
// activity, we need to go ahead and resume it to ensure we complete an
// in-flight app switch.
mRootWindowContainer.resumeFocusedTasksTopActivities();
}
}
}
if (prev != null) {
prev.resumeKeyDispatchingLocked();
}
// 在这里会把paused的activity添加到Stopping列表中
mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
// Notify when the task stack has changed, but only if visibilities changed (not just
// focus). Also if there is an active root pinned task - we always want to notify it about
// task stack changes, because its positioning may depend on it.
if (mTaskSupervisor.mAppVisibilitiesChangedSinceLastPause
|| (getDisplayArea() != null && getDisplayArea().hasPinnedTask())) {
mAtmService.getTaskChangeNotificationController().notifyTaskStackChanged();
mTaskSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
}
}
接下来的调用流程和三.1一样,就不在细致分析,经过一系列调用,来到了新建Task的父类TaskFragment的resumeTopActivity()方法如下:
TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
// 在我之前新建的Task中,topRunningActivity 即为新建的ActivtyRecord
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canResumeByCompat()) {
return false;
}
// 经过刚才的一轮pasue,已经没有处于pausing状态的ActivirtyReord,故allPausedComplete为ture
final boolean allPausedComplete = mRootWindowContainer.allPausedActivitiesComplete();
// 不进入
if (!allPausedComplete) {
ProtoLog.v(WM_DEBUG_STATES,
"resumeTopActivity: Skip resume: some activity pausing.");
return false;
}
.......
` // 所有的Actiity都pause完成了,故pausing为false
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
if (mResumedActivity != null) {
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Pausing %s", mResumedActivity);
pausing |= startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,
next, "resumeTopActivity");
}
// 不进入
if (pausing) {
....
return true;
} else if (mResumedActivity == next && next.isState(RESUMED)
.....
}
// 这里的next的为要启动的Activity,一般情况下,拉起新的进程并attach到服务端的过程比paused的过程慢,假如进程还没完全启动,所以next.attachedToProcess() =false
if (next.attachedToProcess()) {
....
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(false /* taskSwich */);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Restarting %s", next);
// 进一步到这里,需要注意的是 参数为之前新建的ActivtyRecord
mTaskSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
如下会获取之前新建ActivityReocrd的WindowProcessController,因为ActivityRecord的进程还没有完全启动,所以wpc == null,随后流程终止,需要 依靠新启动的应用的进程完全启动后来进一步触发resume流程(当然如果进程启动的比pasue的快的话会进入到realStartActivityLocked去正式开始resume)
ActivityTaskSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
// 获取新建ActivityRecord的 WindowProcessController,因为进程为完全启动这里的 WindowProcessController == null
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
// wpc 为null,流程终止
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
// Remove the process record so it won't be considered as alive.
mService.mProcessNames.remove(wpc.mName, wpc.mUid);
mService.mProcessMap.remove(wpc.getPid());
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
......
五、新进程拉起,执行attach,回调到服务端
上文中提到过,在服务端发起pause的阶段。同时会去拉起新启动应用的进程,具体启动新进程的流程并不是本文的重点,重点关注进程启动做了什么:
在进程启动后,会通过反射构造出ActivityThread对象,随后又会通过反射调用ActivityThread的main()方法。
1. 构造出新应用进程的ActivityThread,随后调用AMS的attachApplication的方法:
ActivityThread.java
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
.....
// 创建出ActivityThread对象
ActivityThread thread = new ActivityThread();
执行ActivityThread的attach方法
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mConfigurationController = new ConfigurationController(this);
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// 获取AMS的代理,执行attachApplication方法
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
....
}
.....
}
ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
.....
try {
// 注册app进程死亡通知处理机制,也就是创建监听app死亡的对象
// App进程死亡后,会调用AppDeathRecipient.binderDied()方法
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.setDeathRecipient(adr);
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
mProcessList.startProcessLocked(app,
new HostingRecord(HostingRecord.HOSTING_TYPE_LINK_FAIL, processName),
ZYGOTE_POLICY_FLAG_EMPTY);
return false;
}
// 接下来又会通过bindApplication回到应用进程,对Application做一些初始化
thread.bindApplication(processName, appInfo,
app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
providerList, null, profilerInfo, null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
.....
if (normalMode) {
try {
didSomething =
// 进一步去触发resume
mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
}
ActivityTaskManagerService.java
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
}
try {
return mRootWindowContainer.attachApplication(wpc);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
}
boolean attachApplication(WindowProcessController app) throws RemoteException {
try {
return mAttachApplicationHelper.process(app);
} finally {
mAttachApplicationHelper.reset();
}
}
AttachApplicationHelper
@Override
public boolean test(ActivityRecord r) {
if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard
|| r.app != null || mApp.mUid != r.info.applicationInfo.uid
|| !mApp.mName.equals(r.processName)) {
return false;
}
try {
//
if (mTaskSupervisor.realStartActivityLocked(r, mApp,
mTop == r && r.getTask().canBeResumed(r) /* andResume */,
true /* checkConfig */)) {
mHasActivityStarted = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity " + mTop, e);
mRemoteException = e;
return true;
}
return false;
}
如下又到了 realStartActivityLocked(),和之前pause流程的后半段的终点一样:
主要做了三件事:
- 判断了有没有完成了pause
- 生成ClientTransaction
- 把生成ClientTransaction通过binder下发给应用端
1. 判断了有没有完成了pause
在realStartActivityLocked方法中开始阶段判断了有没有完成了pause,没有则终止。回忆之前pause的后半段进入到realStartActivityLocked之前会判断新的Activity有没有新进程,没有则不进入。
进一步总结一下:在启动activity的过程中流程会一分为2同时进行:
1.进行pasue,完成后汇报至服务端,检查进程是否拉起,拉起则执行realStartActivityLocked。2. 去拉起新进程,进程运行后汇报到服务端,检查pasue是否已经完成,完成则执行realStartActivityLocked。
故启动过程中realStartActivityLocked的执行条件是 pasue完成 和 启动新进程完成。
2. 生成ClientTransaction
生成ClientTransaction并给ClientTransaction添加了一个类型为LaunchActivityItem的callback和类型为ResumeActivityItem的LifecycleStateRequest。
3. 把生成ClientTransaction通过binder下发给应用端
随后应用端将会执行ClientTransaction对生命周期进行转换
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// 判断是不是所有的activitypaused,如果有 就不往下执行
if (!mRootWindowContainer.allPausedActivitiesComplete()) {
// While there are activities pausing we skipping starting any new activities until
// pauses are complete. NOTE: that we also do this for activities that are starting in
// the paused state because they will first be resumed then paused on the client side.
ProtoLog.v(WM_DEBUG_STATES,
"realStartActivityLocked: Skipping start of r=%s some activities pausing...",
r);
return false;
}
......
// 在这里生成一个 clientTransaction 新启动的应用下发生命周期转换的请求了
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.token);
final boolean isTransitionForward = r.isTransitionForward();
// 生成生命周期事务
final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();
// 给clientTransaction添加了一个类型为 LaunchActivityItem的callback
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
results, newIntents, r.takeOptions(), isTransitionForward,
proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
} else {
lifecycleItem = PauseActivityItem.obtain();
}
// 给clientTransaction添加了一个类型为ResumeActivityItem的LifecycleStateRequest
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
// 把clientTransaction下发给新启动的
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
六、对需要启动的activity进行resum
clientTransaction经过binder来到了应用,接下来应用端将会处理这个clientTransaction。
这次从服务端中传递来的clientTransaction除了有这次从服务端中传递来的clientTransaction除了有callback之外还有行ActivityLifecycleItem之外还有行callback。
在上文梳理的pasue的过程中总结了应用端的对clientTransaction的处理过程,如下:
- 把ClientTransaction通过mClient发送给应用端
- 应用端执行ClientTransaction的preExcute()
a. 遍历callback执行callback的preExecute()
b. 执行ActivityLifecycleItem的preExecute() - 应用端执行ClientTransaction的execute()
a. 遍历callback执行callback的execute()
b. 遍历callback执行callback的postExecute()
c. cycleToPath()
d. 执行ActivityLifecycleItem的execute()
e. 执行ActivityLifecycleItem的postExecute()
对于在这次传递来的ClientTransaction,和生命周期相关的是 cycleToPath(),和 ResumeActivityItem的execute()和postExecute()
- 执行cycleToPath()
- 执行ResumeActivityItem的execute()
- 执行ResumeActivityItem的postExecute()
1. 执行cycleToPath()
执行cycleToPath的excludeLastState为true,所以生成的生命周期路径为 [create, start]
如下:
TransactionExecutor.java
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
final int start = r.getLifecycleState();
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Cycle activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " from: " + getStateName(start) + " to: " + getStateName(finish)
+ " excludeLastState: " + excludeLastState);
}
// 计算出当前生命周期状态到目标生命周期状态的前一个的路径
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
// 按照生成的路径,执行生命周期转换
performLifecycleSequence(r, path, transaction);
}
如下就是遍历path,执行生命周期转变的过程。根据path,将会执行handleLaunchActivity和handleStartActivity
TransactionExecutor.java
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Transitioning activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " to state: " + getStateName(state));
}
switch (state) {
// 执行onCreate
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
// 执行onStart
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions,
null /* activityOptions */);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
1.调用Activity的onCreate方法
构造出要启动的Activity对象,随后调用该Activity的onCreate方法:
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
....
// 构造出了目标Activity,并会调用Activity的onCreate方法
final Activity a = performLaunchActivity(r, customIntent);
....
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
.....
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
// 创建出需要启动的Activity对象
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
appContext.getAttributionSource());
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
// 调用Activity的OnCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
.....
return activity;
}
2.调用Activity的onStart方法
@Override
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, ActivityOptions activityOptions) {
final Activity activity = r.activity;
.....
// 调用对应Activity的onstart方法
// Start
activity.performStart("handleStartActivity");
r.setState(ON_START);
.....
// 更新可见性
updateVisibility(r, true /* show */);
mSomeActivitiesChanged = true;
}
2.执行ResumeActivityItem的execute()
接下来会正式的调用到 ActivityRecord的onResume方法:
ResumeActivityItem.java
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
如下performResumeActivity方法最终会调用到对应Activity的onResume方法。这里只描述onresme的调用流程,实际上activity的resume过程做了很多事情,还是比较复杂的。
ActivityThread.java
@Override
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, String reason) {
// 调用目标Activity的onRsume方法
if (!performResumeActivity(r, finalStateRequest, reason)) {
return;
}
......
}
3.执行ResumeActivityItem的postExecute()
以上流程执行完毕后通过ResumeActivityItem的postExecute()方法通知到服务端:
ResumeActivityItem.java
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// TODO(lifecycler): Use interface callback instead of actual implementation.
ActivityClient.getInstance().activityResumed(token, client.isHandleSplashScreenExit(token));
}
ActivityClient.java
public void activityResumed(IBinder token, boolean handleSplashScreenExit) {
try {
getActivityClientController().activityResumed(token, handleSplashScreenExit);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
https://blog.youkuaiyun.com/xiaoyantan/article/details/126986441