【Android 13】Activity启动流程-2

【接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个主线

  1. pause当前Activity,也就是launcher
  2. 异步创建"电话"的进程

在第一步将launcher的Activity执行pauser, 这一步执行到最后也会触发"电话"应用MainActivity的启动,第二步创建"电话"进程,进程创建完肯定也会执行"电话"应用MainActivity的启动,这么看来就有2个地方触发了。

这是因为是异步创建进程,不知道谁先执行完,但是可以明确的是,"电话"应用MainActivity必须有2个条件:

  1. 前一个Activity执行完pause
  2. 进程创建完成

所以无论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进行打印的。

相关推荐
JavaNoober13 分钟前
Android 前台服务 "Bad Notification" 崩溃机制分析文档
android
城东米粉儿1 小时前
关于ObjectAnimator
android
zhangphil2 小时前
Android渲染线程Render Thread的RenderNode与DisplayList,引用Bitmap及Open GL纹理上传GPU
android
火柴就是我3 小时前
从头写一个自己的app
android·前端·flutter
lichong9514 小时前
XLog debug 开启打印日志,release 关闭打印日志
android·java·前端
用户69371750013844 小时前
14.Kotlin 类:类的形态(一):抽象类 (Abstract Class)
android·后端·kotlin
火柴就是我4 小时前
NekoBoxForAndroid 编译libcore.aar
android
Kaede66 小时前
MySQL中如何使用命令行修改root密码
android·mysql·adb
明君879977 小时前
Flutter 图纸标注功能的实现:踩坑与架构设计
android·ios
成都大菠萝7 小时前
Android Auto开发(3)-Audio Integration
android