【接Activity发动流程-1最终的流程】在ActivityStarer::startActivityInner办法中,经过getOrCreateRootTask办法创立Task,然后经过setNewTask办法将新建的ActivityRecord进行挂在到新建的Task上,接下来将需求处理新的Activity发动和显现逻辑。
后续的流程由resumeFocusedTasksTopActivities履行。
显现Activity resumeFocusedTasksTopActivities
调用链
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 发动“电话”的场景
# 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
# 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。
# 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
# 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的发动。
# ActivityClient
public void activityPaused(IBinder token) {
try {
getActivityClientController().activityPaused(token);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
getActivityClientController回来的是ActivityClientController方针。
调用链
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可见。究竟不能让用户什么都看不见, 总得显现一个吧
主流程盯梢
接下来进入代码剖析
# 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
# 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
# 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而已。
# 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。
# 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
# 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
# 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次
# 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这块履行进程创立的调用流程
# 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 来发动运用进程
履行完后输出日志
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进行打印的。