【接Activity启动流程-1最后的流程】在ActivityStarer::startActivityInner方法中,通过getOrCreateRootTask方法创建Task,而后通过setNewTask方法将新建的ActivityRecord进行挂在到新建的Task上,接下来将需要处理新的Activity启动和显示逻辑。
后续的流程由resumeFocusedTasksTopActivities执行。
显示Activity resumeFocusedTasksTopActivities
调用链
arduino
RootWindowContainer::resumeFocusedTasksTopActivities
Task::resumeTopActivityUncheckedLocked
Task::resumeTopActivityInnerLocked
TaskFragment::resumeTopActivity
TaskDisplayArea::pauseBackTasks -- 2.2.1 pause LauncherActivity
WindowContainer::forAllLeafTask
TaskFragment::forAllLeafTaskFragments
TaskFragment::startPausing
TaskFragment::startPausing
TaskFragment::schedulePauseActivity --构建 PauseActivityItem,这里是触发暂停launch
ActivityTaskManagerService::startProcessAsync -- 2.2.2创建"电话"进程
主流程跟踪
经过几次调用会执行到TaskFragment::resumeTopActivity方法,这个方法非常复杂,场景不同执行的分支也不同,值得重点分析。而且很多重要的逻辑都集中在这里,我觉得后续会被重构的。 当前还是只分析launcher 启动"电话"的场景
java
# TaskFragment
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
// 这里的next返回的是 电话的main activity,表示下一个需要现实的
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
......
// 如果跳过的这些逻辑都没执行return,则正在开始执行 resume流程,打印关键日志。
// 前面流程如果返回也有响应日志的打印
// 打印日志,需要显示哪个Activity
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
......
// 重点* 1. 这里会将 launch的Activity pause 。参数是 电话的ActivityRecord
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
......
if (pausing) {
ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: Skip resume: need to"+ " start pausing");
if (next.attachedToProcess()) {
......
} else if (!next.isProcessRunning()) {
// 重点*2. 进程没有运行,则触发异步创建进程。 当前逻辑肯定是执行这一条
final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
}
......
// 注意,这里会return,
return true;
}
......
//后面还有重要逻辑,当前可忽略
}
重点分析: 上面说过这个函数非常复杂,在当前逻辑有2个主线
- pause当前Activity,也就是launcher
- 异步创建"电话"的进程
在第一步将launcher的Activity执行pauser, 这一步执行到最后也会触发"电话"应用MainActivity的启动,第二步创建"电话"进程,进程创建完肯定也会执行"电话"应用MainActivity的启动,这么看来就有2个地方触发了。
这是因为是异步创建进程,不知道谁先执行完,但是可以明确的是,"电话"应用MainActivity必须有2个条件:
- 前一个Activity执行完pause
- 进程创建完成
所以无论2个分支哪一个先执行完,都需要等后一个执行完的来触发后续电话"应用MainActivity的启动。
先看launcher的pause流程
1. pause 流程 pauseBackTasks
需要显示新的Activity,那么之前的肯定是要执行pause的,就在这里执行。参数next为"电话的"ActivityRecord
java
# TaskDisplayArea
// 可以看到"电话"ActivityRecord在这里就被称为resuming
boolean pauseBackTasks(ActivityRecord resuming) {
final int[] someActivityPaused = {0};
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.
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;
}
forAllLeafTasks和forAllLeafTaskFragments在【WMS/AMS 常见方法调用提取】有解释,那么当前这段方法其实就是让DefaultTaskDisplayArea下的每个叶子LeafTaskFragments执行startPausing。
typescript
# TaskFragment
boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
String reason) {
......
// 日志输出当前TaskFragment和mResumedActivity的关系。后面会贴上日志证明
ProtoLog.d(WM_DEBUG_STATES, "startPausing: taskFrag =%s " + "mResumedActivity=%s", this,
mResumedActivity);
......
// 后面的prev就是launcher的ActivityRecord了
ActivityRecord prev = mResumedActivity;
......
// 输出日志
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSING: %s", prev);
mPausingActivity = prev;
mLastPausedActivity = prev;
if (!prev.finishing && prev.isNoHistory()
&& !mTaskSupervisor.mNoHistoryActivities.contains(prev)) {
mTaskSupervisor.mNoHistoryActivities.add(prev);
}
// 设置window状态为PAUSING
prev.setState(PAUSING, "startPausingLocked");
prev.getTask().touchActiveTime();
......
if (prev.attachedToProcess()) {
// launcher的进程肯定是满足条件的
if (shouldAutoPip) {
boolean didAutoPip = mAtmService.enterPictureInPictureMode(
prev, prev.pictureInPictureArgs);
ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
+ "directly: %s, didAutoPip: %b", prev, didAutoPip);
} else {
// 重点*1. 根据堆栈是执行这里。上面的PIP日志没输出,也能确定是走的这个
schedulePauseActivity(prev, userLeaving, pauseImmediately, reason);
}
}
......
}
void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, String reason) {
// 输出日志
ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
try {
// 输出events 日志
EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving, reason);
// 重点构建并执行PauseActivityItem
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.token, 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;
mTaskSupervisor.mNoHistoryActivities.remove(prev);
}
}
最终在TaskFragment::schedulePauseActivity构建并执行了launcher的pause事件。 这块相关的日志输入如图: 因为是后面补充的所以对象不一样,但是能确定这里处理的TaskFragment和mResumedActivity都是launcher对象的。
tip: State movement这段的输出是在ActivityRecord::setState 只有状态改变都会输出
接下来的重点是看PauseActivityItem的执行逻辑
1.1 PauseActivityItem
typescript
# PauseActivityItem
@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
// 重点*1. 触发 handlePauseActivity 流程
client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@Override
public int getTargetState() {
return ON_PAUSE;
}
// pauser执行后调用 postExecute
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mDontReport) {
return;
}
// 重点*2. 触发启动新的Activity
ActivityClient.getInstance().activityPaused(token);
}
默认已经知道ClientTransaction调用逻辑,不知道移步【】 这里先执行execute 的逻辑,也就是 launcher的pause流程,这个不是主线,单独解释【】。然后执行postExecute。这里会触发新Activity的启动。
scss
# ActivityClient
public void activityPaused(IBinder token) {
try {
getActivityClientController().activityPaused(token);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
getActivityClientController返回的是ActivityClientController对象。
调用链
arduino
ActivityClientController::activityPaused
ActivityRecord::activityPaused
TaskFragment::completePause
RootWindowContainer::resumeFocusedTasksTopActivities --分支1 ,再次执行 resumeFocusedTasksTopActivities
RootWindowContainer::resumeFocusedTasksTopActivities
Task::resumeTopActivityUncheckedLocked
Task::resumeTopActivityInnerLocked
TaskFragment::resumeTopActivity
ActivityTaskSupervisor::startSpecificActivity --触发 startSpecificActivity 判断应用是否创建
RootWindowContainer::ensureActivitiesVisible --分支2
RootWindowContainer::ensureActivitiesVisible
DisplayContent::ensureActivitiesVisible
WindowContainer::forAllRootTasks --忽略固定逻辑
Task::ensureActivitiesVisible
Task::forAllLeafTasks --忽略固定逻辑
TaskFragment::updateActivityVisibilities
EnsureActivitiesVisibleHelper::process
EnsureActivitiesVisibleHelper::setActivityVisibilityState
EnsureActivitiesVisibleHelper::makeVisibleAndRestartIfNeeded
ActivityTaskSupervisor::startSpecificActivity --触发 startSpecificActivity 判断应用是否创建
调用堆栈如下:
不是每个函数都要去跟,没有意义,跟踪重点函数,关注重点处理的地方即可。 否则下个版本重构后,就完全不一样。 所以只需要记住重点做的事情就好。 这边又2个地方都会出发ActivityTaskSupervisor::startSpecificActivity,而且都是由ActivityClientController::activityPaused为源头。 由activityPaused方法名也能知道这段逻辑是在launcher 执行完pause后再执行的
注意这里在第一个分支 RootWindowContainer::resumeFocusedTasksTopActivities到TaskFragment::resumeTopActivity直接的调用栈和上一篇是一样的,只不过最后执行的不一样而已
pause后,虽然又2个分支,但是根据函数名,其实都是为了能让下一个Activity可见。毕竟不能让用户什么都看不见, 总得显示一个吧
主流程跟踪
接下来进入代码分析
typescript
# ActivityRecord
void activityPaused(boolean timeout) {
......
if (pausingActivity == this) {
// 打印日志
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
(timeout ? "(due to timeout)" : " (pause complete)"));
mAtmService.deferWindowLayout();
try {
// 进入下一步,注入第二个参数为null
taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
} finally {
mAtmService.continueWindowLayout();
}
return;
}
......
}
// 打印如下
WindowManager: Moving to PAUSED: ActivityRecord{1f58beb u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t8} (pause complete)
//TaskFragment::completePause
# TaskFragment
@VisibleForTesting
void completePause(boolean resumeNext, ActivityRecord resuming) {
// 拿到先去的Activity,也就是需要 pause的
ActivityRecord prev = mPausingActivity;
ProtoLog.v(WM_DEBUG_STATES, "Complete pause: %s", prev);
if (prev != null) {
......
// 设置窗口状态为PAUSED
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) {
...... 如果已经finish,上面还在设置 pause,那正常应该是还没finish
} else if (prev.hasProcess()) {
// 打印状态日志
ProtoLog.v(WM_DEBUG_STATES, "Enqueue pending stop if needed: %s "
+ "wasStopping=%b visibleRequested=%b", prev, wasStopping,prev.mVisibleRequested);
}else {
......
}
if (resumeNext) {
......
// 重点* 1. 第1个分支
mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev,null /* targetOptions */);
......
}
......
// 重点* 2.
mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
......
}
}
结合前面TaskFragment::resumeTopActivity的创建进程,然后根据堆栈知道这2个分支也也创建新进程,那已知3地方触发创建进程。
这里的 topRootTask 就是SourceActivity"电话"的Activity,prev是launcher的,resuming为null。
1.1.1 分支1 resumeFocusedTasksTopActivities
arduino
# TaskFragment
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
......
// pause
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
......
if (pausing) {
......
// 启动进程
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
......
//return,
return true;
}
// 本次逻辑走这
......
// pause 逻辑会再次走到这,新进程目前还没有启动所以走else
if (next.attachedToProcess()) {
......
} else {
......
// 打印log
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Restarting %s", next);
// 重点* 执行startSpecificActivity
mTaskSupervisor.startSpecificActivity(next, true, true);
}
}
又是TaskFragment::resumeTopActivity方法,这次是直接走到这个方法的最下面,启动Activity。
1.1.2 ensureActivitiesVisible分支
看方法名是为了 Activity的可见 根据上面的调用链,会执行到 DisplayContent::ensureActivitiesVisible
scss
# DisplayContent
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
if (mInEnsureActivitiesVisible) {
// Don't do recursive work.
return;
}
mInEnsureActivitiesVisible = true;
mAtmService.mTaskSupervisor.beginActivityVisibilityUpdate();
try {
forAllRootTasks(rootTask -> {
rootTask.ensureActivitiesVisible(starting, configChanges, preserveWindows,
notifyClients);
});
if (mTransitionController.isCollecting()
&& mWallpaperController.getWallpaperTarget() != null) {
// Also update wallpapers so that their requestedVisibility immediately reflects
// the changes to activity visibility.
// TODO(b/206005136): Move visibleRequested logic up to WindowToken.
mWallpaperController.adjustWallpaperWindows();
}
} finally {
mAtmService.mTaskSupervisor.endActivityVisibilityUpdate();
mInEnsureActivitiesVisible = false;
}
}
这里拿出来主要是遇到了forAllRootTasks这个方法,其实就和之前的forAllLeafTasks使用方式是一样的。对每个rootTask执行Lambda而已。
java
# Task
void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
mTaskSupervisor.beginActivityVisibilityUpdate();
try {
forAllLeafTasks(task -> {
task.updateActivityVisibilities(starting, configChanges, preserveWindows,
notifyClients);
}, true /* traverseTopToBottom */);
if (mTranslucentActivityWaiting != null &&
mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
// Nothing is getting drawn or everything was already visible, don't wait for
// timeout.
notifyActivityDrawnLocked(null);
}
} finally {
mTaskSupervisor.endActivityVisibilityUpdate();
}
}
这里又有个forAllLeafTasks,调用每个叶子Task的updateActivityVisibilities方法,但是Task的这个方法是气父类TaskFragmet里定义的,所以看TaskFragmet。
java
# TaskFragmet
private final EnsureActivitiesVisibleHelper mEnsureActivitiesVisibleHelper =
new EnsureActivitiesVisibleHelper(this);
final void updateActivityVisibilities(@Nullable ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
mTaskSupervisor.beginActivityVisibilityUpdate();
try {
// 重点
mEnsureActivitiesVisibleHelper.process(
starting, configChanges, preserveWindows, notifyClients);
} finally {
mTaskSupervisor.endActivityVisibilityUpdate();
}
}
我们知道这一条线都是为了处理Activity可见的。 在这定义了一个专门的类来处理。 不过需要注意的是,这个方法会执行多次,因为他是遍历每一个符合条件的子容器,从上到下遍历。
1.1.3 EnsureActivitiesVisibleHelper::process
java
# EnsureActivitiesVisibleHelper
void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) {
// 调用 reset 方法,对传入的参数进行重置处理
reset(starting, configChanges, preserveWindows, notifyClients);
......
for (int i = mTaskFragment.mChildren.size() - 1; i >= 0; --i) {
// 获取当前子元素
final WindowContainer child = mTaskFragment.mChildren.get(i);
// 将当前子元素转换为TaskFragment,只有TaskFragment重写了,Task或ActivityRecord为null
// Task的孩子一般就是ActivityRecord或者Task
final TaskFragment childTaskFragment = child.asTaskFragment();
if (childTaskFragment != null
&& childTaskFragment.getTopNonFinishingActivity() != null) {
......
} else {
// 只有ActivityRecord重写了
setActivityVisibilityState(child.asActivityRecord(), starting, resumeTopActivity);
}
}
}
private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
final boolean resumeTopActivity) {
......
if (reallyVisible) {
.......
if (!r.attachedToProcess()) {
// 主流程
makeVisibleAndRestartIfNeeded(mStarting, mConfigChanges, isTop,
resumeTopActivity && isTop, r);
} else {
......
}
} else {
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+ " finishing=" + r.finishing + " state=" + r.getState()
+ " containerShouldBeVisible=" + mContainerShouldBeVisible
+ " behindFullyOccludedContainer=" + mBehindFullyOccludedContainer
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
}
// 不可见调用makeInvisible
r.makeInvisible();
}
}
这里的r 表示需要启动的ActivityRecord,当前流程还是onPause的流程。并没有知道创建进程那一步,所以进程是没有attached的。那就会执行makeVisibleAndRestartIfNeeded
arduino
# EnsureActivitiesVisibleHelper
private void makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
boolean isTop, boolean andResume, ActivityRecord r) {
......
if (!r.mVisibleRequested || r.mLaunchTaskBehind) {
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
}
// 设置Visibility
r.setVisibility(true);
}
if (r != starting) {
mTaskFragment.mTaskSupervisor.startSpecificActivity(r, andResume,
true /* checkConfig */);
}
}
1.1.4 ActivityTaskSupervisor::startSpecificActivity
这个方法也被调用了2次
java
# ActivityTaskSupervisor
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
// 拿到目标进程信息
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
// 进程是否存在,且主线程已执行
if (wpc != null && wpc.hasThread()) {
try {
// 进程进程 则执行 realStartActivityLocked 流程
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);1111111111
}
......
}
......
// 异步启动进程
mService.startProcessAsync(r, knownToBeDead, isTop,
isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_ACTIVITY);
}
这里有2个分支,如果目标进程创建了,则走realStartActivityLocked,否则执行创建的逻辑。不过就目前2个调用的地方都是执行onPause的逻辑性,这里还是其实都是制作到startProcessAsync。 而不会走进realStartActivityLocked
2 创建进程逻辑
这里是回到执行pause的同级流程,也就是最前面的TaskFragment::resumeTopActivity 执行pause后会执行 ActivityTaskManagerService::startProcessAsync,最后也是通过 ActivityManagerService来触发启动进程的。 看看AMS这块执行进程创建的调用流程
java
# ATMS
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
try {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
+ activity.processName);
}
// 发生消息,启动进程,调用ActivityManagerInternal::startProcess
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
// ActivityManagerInternal::startProcess 的实现在AMS的内部类 LocalService 中
# AMS.LocalService
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
// 重点调用
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
null /* sdkSandboxClientAppPackage */,
null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
# ProcessList
boolean startProcessLocked(......) {
......
mService.mProcStartHandler.post(() -> handleProcessStart(
app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
requiredAbi, instructionSet, invokeWith, startSeq));
......
}
private void handleProcessStart(......) {
创建一个用于启动进程的 Runnable 对象
final Runnable startRunnable = () -> {
try { // 调用 startProcess 方法启动进程,并获取启动结果 ProcessStartResult
final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(),
entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags,
mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith,
app.getStartTime());
// 在锁定 ActivityManagerService 后,处理进程启动结果
synchronized (mService) {
handleProcessStartedLocked(app, startResult, startSeq);
}
} catch (RuntimeException e) {
......异常处理
}
};
// // 如果有前任进程并且前任进程正在死亡中
final ProcessRecord predecessor = app.mPredecessor;
if (predecessor != null && predecessor.getDyingPid() > 0) {
// 通过前任进程执行启动进程的 Runnable 对象
handleProcessStartWithPredecessor(predecessor, startRunnable);
} else {
// 如果没有前任进程或前任进程未死亡,直接运行启动进程的 Runnable 对象
// 走的是这个逻辑
startRunnable.run();
}
}
通过 startProcess 来启动应用进程
执行完后输出日志
ruby
07-26 19:19:05.477 8737 8782 I ActivityManager: Start proc 19643:com.example.myapplication/u0a198 for next-top-activity {com.example.myapplication/com.example.myapplication.MainActivity}
这段日志是在 ProcessList::handleProcessStart 方法里构建了个StringBuilder,然后传递给AMS::reportUidInfoMessageLocked进行打印的。