系统启动流程分析之Launcher应用启动流程分析(下)

463 阅读9分钟

「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。

Launcher启动流程分析(下)

在此前的两篇文档Launcher启动流程分析(上) Launcher启动流程分析(中)中有分析过,从SystemServer中启动AMS后,通过AMS的systemReady函数启动Launcher应用的启动流程,在这个过程中,通过调用ActivityStarter的execute函数,最终会在ActivityStarter对象的startActivityInner函数中,通过ActivityStack的startActivityLocked函数来将对应的ActivityRecord添加到ActivityStack中,并且通过RootWindowContainer对象的resumeFocusedStacksTopActivities函数来启动这个Activity,本篇我们将来分析下这个流程,以及最终Launcher应用的主界面显示的具体过程

ActivityRecord对象添加到ActivityStack流程分析

ActivityRecord类是包含了Activity具体信息的一个类,且其一般被用作添加到ActivityStack堆栈中的实例,此处通过ActivityStack的startActivityLocked函数完成添加任务

// 注:此处传入的第一个参数ActivityRecord对象为在ActivityStarter.executeRequest函数中初始化的一个ActivityRecord对象
// 第二个参数为包含有Launcher应用的主Activity信息的一个ActivityRecord对象
// 第三个参数newTask为true
// 第四个参数keepCurTransition为false
// 第五个参数options为ActivityStartController对象调用startHomeActivity时初始化的一个ActivityOptions
//      和后续新建的SafeActivityOptions对象后设置的一个ActivityOptions对象的融合
void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity,
        boolean newTask, boolean keepCurTransition, ActivityOptions options) {
    // 从前述的代码中分析,此处获取到的Task不为null
    Task rTask = r.getTask();
    // 根据代码判断,此处options.getAvoidMoveToFront()并未有设置过,因此此处为false,即整体的allowMoveToFront参数为true
    // 根据判断,此处isOrhasTask参数返回值为true
    final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
    final boolean isOrhasTask = rTask == this || hasChild(rTask);
    // mLaunchTaskBehind tasks get placed at the back of the task stack.
    if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {
        // Last activity in task had been removed or ActivityManagerService is reusing task.
        // Insert or replace.
        // Might not even be in.
        // 将当前的rTask参数设置为
        positionChildAtTop(rTask);
    }
    Task task = null;
    if (!newTask && isOrhasTask) {
        // ...... 分支无法运行,此处newTask为true,因此跳过
    }

    // Place a new activity at top of stack, so it is next to interact with the user.

    // If we are not placing the new activity frontmost, we do not want to deliver the
    // onUserLeaving callback to the actual frontmost activity
    final Task activityTask = r.getTask();
    if (task == activityTask && mChildren.indexOf(task) != (getChildCount() - 1)) {
        // ...... 分支无法运行,此处newTask为true,因此跳过
    }

    task = activityTask;

    // ...... 日志打印代码省略
    // 接下来将上述初始化的ActivityRecord对象放置到当前的Task中的mWindowList中的最上层
    task.positionChildAtTop(r);

    // The transition animation and starting window are not needed if {@code allowMoveToFront}
    // is false, because the activity won't be visible.
    // 此处由于前述代码将ActivityRecord添加到Task中,此处的hasActivity()函数将返回true
    // 而前述分析allowMoveToFront = true
    // 因此此处if分支会进入
    if ((!isHomeOrRecentsStack() || hasActivity()) && allowMoveToFront) {
        // ...... 此处对于Activity的启动模式等进行设置,不再赘述
    }
    // ...... 无效分支代码省略
}

从这段代码可知,此处最主要的任务是将ActivityRecord对象存放于Task对象参数mWindowList的最上层TOP,当然从前述代码分析可知,此处实质上是一个继承自Task类的ActivityStack对象

此后通过其他方式将当前的Activity启动

Activity的具体启动流程

由前文分析可知,在Activity的启动过程中,主要是通过RootWindowContainer的resumeFocusedStacksTopActivities函数将对应添加到Task对象(ActivityStack对象)中的ActivityRecord对象运行起来

RootWindowContainer.java
boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    // ...... 条件判断不满足,代码省略

    boolean result = false;
    // 分析前述的代码可知,此处的targetStack.isTopStackInDisplayArea函数返回为true
    if (targetStack != null && (targetStack.isTopStackInDisplayArea()
            || getTopDisplayFocusedStack() == targetStack)) {
        // 调用对应的ActivityStack对象targetStack的resumeTopActivityUncheckedLocked函数
        // 注意此处传入的两个参数,均是从ActivityStarter中传入的,target包含了需要启动的Activity的基本信息的ActivityRecord对象
        // targetOptions为此前说明过的ActivityStartController对象调用startHomeActivity时初始化的一个ActivityOptions
        //      和后续新建的SafeActivityOptions对象后设置的一个ActivityOptions对象的融合
        result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    // ...... 与功能暂不相关,暂不分析,代码省略
    return result;
}

ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    // ...... 条件判断不满足代码省略

    boolean result = false;
    try {
        // Protect against recursion.
        mInResumeTopActivity = true;
        // 继续调用resumeTopActivityInnerLocked函数
        result = resumeTopActivityInnerLocked(prev, options);

        // ......
    } finally {
        mInResumeTopActivity = false;
    }

    return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // ...... 条件判断不满足代码省略

    // Find the next top-most activity to resume in this stack that is not finishing and is
    // focusable. If it is not focusable, we will fall into the case below to resume the
    // top activity in the next focusable task.
    ActivityRecord next = topRunningActivity(true /* focusableOnly */);

    final boolean hasRunningActivity = next != null;

    // ...... 条件判断不满足代码省略

    mRootWindowContainer.cancelInitializingActivities();

    // Remember how we'll process this pause/resume situation, and ensure
    // that the state is reset however we wind up proceeding.
    boolean userLeaving = mStackSupervisor.mUserLeaving;
    mStackSupervisor.mUserLeaving = false;

    // ...... 条件判断不满足代码省略

    next.delayedResume = false;
    final TaskDisplayArea taskDisplayArea = getDisplayArea();

    // ...... 条件判断不满足代码省略

    // The activity may be waiting for stop, but that is no longer
    // appropriate for it.
    mStackSupervisor.mStoppingActivities.remove(next);
    next.setSleeping(false);

    // ...... 条件判断不满足代码省略
    mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);

    ActivityRecord lastResumed = null;
    final ActivityStack lastFocusedStack = taskDisplayArea.getLastFocusedStack();
    // ...... 条件判断不满足代码省略

    // We are starting up the next activity, so tell the window manager
    // that the previous one will be hidden soon.  This way it can know
    // to ignore it when computing the desired screen orientation.
    boolean anim = true;
    final DisplayContent dc = taskDisplayArea.mDisplayContent;
    // ...... 条件判断不满足代码省略

    if (anim) {
        next.applyOptionsLocked();
    } else {
        next.clearOptionsLocked();
    }

    mStackSupervisor.mNoAnimActivities.clear();

    if (next.attachedToProcess()) {
        //  ...... 条件判断不满足代码省略
    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            if (SHOW_APP_STARTING_PREVIEW) {
                next.showStartingWindow(null /* prev */, false /* newTask */,
                        false /* taskSwich */);
            }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
        }
        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        // 此处最终会调用这边的startSpecificActivity函数
        mStackSupervisor.startSpecificActivity(next, true, true);
    }
    return true;
}

从如上的代码看,此处最终会调用ActivityStackSupervisor对象的startSpecificActivity函数

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // ...... 功能无关代码省略

    final boolean isTop = andResume && r.isTopRunningActivity();
    mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}

此处会调用ATMS的startProcessAsync函数

ATMS.java
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
        String hostingType) {
    try {
        // ......
        // Post message to start process to avoid possible deadlock of calling into AMS with the
        // ATMS lock held.
        final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                isTop, hostingType, activity.intent.getComponent());
        mH.sendMessage(m);
    }
    // ......
}

可以看到,这边主要是通过PooledLambda对象的obtainMessage函数来初始化一个Message,然后在ATMS.H对象中处理

static <A, B, C, D, E, F, G> Message obtainMessage(
        HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
                ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
    synchronized (Message.sPoolSync) {
        PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
                function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
                null, null, null);
        return Message.obtain().setCallback(callback.recycleOnUse());
    }
}

此处直接初始化了一个PooledRunnable对象,然后通过Message对象的setCallback函数设置该回调 了解Handler处理消息的流程可知,在Handler调用sendMessage发送消息的时候,会将Message添加到Handler对应的MessageQueue中,从而在对应的Looper对象中通过无限循环从MessageQueue中获取对应的Message,并且调用对应的Handler对象的dispatchMessage函数来分发消息,而在Handler的dispatchMessage函数中

Handler.java
public void dispatchMessage(@NonNull Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}

也就是说,当Handler的dispatchMessage被调用时,若Message的callback回调函数参数被设置,则直接调用Handler的handleCallback函数

private static void handleCallback(Message message) {
    message.callback.run();
}

也就是说,此处会运行这个callback 再回头看下PooledRunnable类的结构

classDiagram
PooledLambda <|-- PooledRunnable
Runnable <|-- PooledRunnable
ThrowingRunnable <|-- PooledRunnable
TraceNameSupplier <|-- PooledRunnable
<<interface>>PooledRunnable
<<interface>>PooledLambda
<<interface>>Runnable
<<interface>>ThrowingRunnable
<<interface>>TraceNameSupplier

也就是说,此处的PooledRunnable是一个Runnable对象,因此,调用其run函数,最终会运行到上述生成Message是传入的第一个参数ActivityManagerInternal::startProcess函数索引,

classDiagram
ActivityManagerService *-- LocalService
ActivityManagerInternal <|-- LocalService

而追踪ActivityManagerInternal对象mAmInternal的实例,会发现它为AMS.LocalService对象,因此

// 此处需要注意的是,这边函数中传入的六个参数,追踪其代码可以知道,在Message通过PooledLambda.obtainMessage函数初始化的时候
// 第一个参数为函数索引,第二个参数为实质调用第一个函数索引参数的对象实例,第3-8个参数即为此处传入的六个参数
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
        boolean isTop, String hostingType, ComponentName hostingName) {
    try {
        // ......
        synchronized (ActivityManagerService.this) {
            // If the process is known as top app, set a hint so when the process is
            // started, the top priority can be applied immediately to avoid cpu being
            // preempted by other processes before attaching the process of top app.
            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                    new HostingRecord(hostingType, hostingName, isTop),
                    ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                    false /* isolated */, true /* keepIfLarge */);
        }
    }
    // ......
}

final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
            hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
            keepIfLarge, null /* ABI override */, null /* entryPoint */,
            null /* entryPointArgs */, null /* crashHandler */);
}

ProcessList.java
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
        int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
        boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
        Runnable crashHandler) {
    long startTime = SystemClock.uptimeMillis();
    ProcessRecord app;
    if (!isolated) {
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
        checkSlow(startTime, "startProcess: after getProcessRecord");

        if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
            // ...... 分支代码省略
        } else {
            // When the user is explicitly starting a process, then clear its
            // crash count so that we won't make it bad until they see at
            // least one crash dialog again, and make the process good again
            // if it had been bad.
            // ...... 日志打印代码省略
            mService.mAppErrors.resetProcessCrashTimeLocked(info);
            if (mService.mAppErrors.isBadProcess(info.processName, info.uid)) {
                // ...... 日志打印代码省略
                mService.mAppErrors.clearBadProcess(info.processName, info.uid);
                if (app != null) {
                    app.bad = false;
                }
            }
        }
    }
    // ...... 分支代码省略

    if (app == null) {
        checkSlow(startTime, "startProcess: creating new process record");
        // 创建一个ProcessRecord,并将其添加到ProcessList中
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
        // ...... 分支代码省略
        app.crashHandler = crashHandler;
        app.isolatedEntryPoint = entryPoint;
        app.isolatedEntryPointArgs = entryPointArgs;
        if (precedence != null) {
            app.mPrecedence = precedence;
            precedence.mSuccessor = app;
        }
        checkSlow(startTime, "startProcess: done creating new process record");
    }
    // ...... 分支代码省略

    // 调用startProcessLocked函数启动上述创建的ProcessRecord
    final boolean success =
            startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
    checkSlow(startTime, "startProcess: done starting proc!");
    return success ? app : null;
}

boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
        int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
        boolean mountExtStorageFull, String abiOverride) {
    // ......

    try {
        // ......
        final String seInfo = app.info.seInfo
                + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
        // Start the process.  It will either succeed and return a result containing
        // the PID of the new process, or else throw a RuntimeException.
        final String entryPoint = "android.app.ActivityThread";
        // 最终会在调用同名函数startProcessLocked
        return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
                instructionSet, invokeWith, startTime);
    }
    // ...... catch remoteexception code delete
}

boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
        int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    app.pendingStart = true;
    app.killedByAm = false;
    app.removed = false;
    app.killed = false;
    // ......
    app.mDisabledCompatChanges = null;
    if (mPlatformCompat != null) {
        app.mDisabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info);
    }
    final long startSeq = app.startSeq = ++mProcStartSeqCounter;
    app.setStartParams(uid, hostingRecord, seInfo, startTime);
    app.setUsingWrapper(invokeWith != null
            || Zygote.getWrapProperty(app.processName) != null);
    mPendingStarts.put(startSeq, app);

    if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
        // ......
        // 直接运行对应的Runnable并运行
        mService.mProcStartHandler.post(() -> handleProcessStart(
                app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
                requiredAbi, instructionSet, invokeWith, startSeq));
        return true;
    } else {
        // ......
    }
}

private void handleProcessStart(final ProcessRecord app, final String entryPoint,
        final int[] gids, final int runtimeFlags, int zygotePolicyFlags,
        final int mountExternal, final String requiredAbi, final String instructionSet,
        final String invokeWith, final long startSeq) {
    // ......
    try {
        // startProcess,这边会启动ActivityThread对象
        final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
                entryPoint, app, app.startUid, gids, runtimeFlags, zygotePolicyFlags,
                mountExternal, app.seInfo, requiredAbi, instructionSet, invokeWith,
                app.startTime);

        synchronized (mService) {
            handleProcessStartedLocked(app, startResult, startSeq);
        }
    }
    // ......
}

private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
        int mountExternal, String seInfo, String requiredAbi, String instructionSet,
        String invokeWith, long startTime) {
    try {
        // ......
        // 根据此前的代码,此处的hostingRecord.mHostingZygote = REGULAR_ZYGOTE
        final Process.ProcessStartResult startResult;
        if (hostingRecord.usesWebviewZygote()) {
            // ......
        } else if (hostingRecord.usesAppZygote()) {
            // ......
        } else {
            // 启动进程,这边的entruPoint = "android.app.ActivityThread"
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                    isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                    whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                    new String[]{PROC_START_SEQ_IDENT + app.startSeq});
        }
        checkSlow(startTime, "startProcess: returned from zygote!");
        return startResult;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

最后通过Process的start函数,在zygote中fork一个相应的进程,并且通过此处的ActivityThread对象的main函数以及传入的参数,调用相关的函数来初始化应用 其实从这块代码来看,ActivityThread对象是每一个进程都包含一个该对象,当然,这个对象肯定需要在AMS中进行注册

总结

如上,此篇我们分析了Launcher应用进程的启动流程,ActivityThread对象的初始化,以及zygote启动ActivityThread的具体方式,待后续再对代码进行深入研究

本篇主要分析的代码流程如下

  1. 在ActivityStarter对象的executeRequest函数中初始化ActivityRecord对象后,通过ActivityStack的startActivityLocked函数,将该ActivityRecord对象插入到ActivityStack对象的mWindowList的TOP位置保存
  2. 通过RootWindowContainer的resumeFocusedStacksTopActivities函数,调用到ActivityStack的resumeTopActivityUncheckedLocked函数,并最终调用ActivityStackSupervisor对象的startSpecificActivity函数
  3. 在startSpecificActivity函数中,通过ATMS的startProcessAsync函数,最终调用AMS.LocalService的startProcess函数,从而通过zygote进程初始化Launcher应用进程,并且通过ActivityThread入口启动Launcher应用的主界面
  4. ActivityThread是应用进程的入口,且每一个应用进程中都包含一个ActivityThread对象,当然此对象会在AMS中进行注册纳入管理

Launcher应用进程启动流程图

图片.png