【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进行打印的。

相关推荐
C4rpeDime12 分钟前
自建MD5解密平台-续
android
鲤籽鲲2 小时前
C# Random 随机数 全面解析
android·java·c#
m0_548514776 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php
凤邪摩羯6 小时前
Android-性能优化-03-启动优化-启动耗时
android
凤邪摩羯6 小时前
Android-性能优化-02-内存优化-LeakCanary原理解析
android
喀什酱豆腐7 小时前
Handle
android
m0_748232928 小时前
Android Https和WebView
android·网络协议·https
m0_748251728 小时前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)
android·游戏·unity
m0_7482546610 小时前
go官方日志库带色彩格式化
android·开发语言·golang
zhangphil10 小时前
Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现“刮刮乐”效果,Kotlin(2)
android·kotlin