Android--Activity启动过程梳理

概述

当从某一个Activity跳转打开另一个Activity显示在屏幕,其中涉及的Activity的启动过程大致分为5部分内容:

  1. 当前Activity调用ATMS系统进程过程;

  2. ATMS向AMS发送创建应用进程的过程;

  3. AMS向Zygote进程发送创建应用进程ActivityThread的过程;

  4. Zygote进程fork复制进程并启动应用进程;

  5. 应用进程ActivityThread启动Activity的过程;

1. 当前Activity调用ATMS系统进程过程

当从某个Activity要跳转到一个未启动的Activity时,当前的Activity会调用startActivity(),传入目标Activity的Intent来开始启动的过程。

  1. 首先会在Activity类中对当前Activity和目标Activity做一些处理,移除当前活动的恢复能力,暂停当前活动,并将恢复能力添加到目标Activity的Intent意图中,然后会调用Activity类的startActivityForResult()方法中,对传入的参数做一些处理,以及Activity启动后结果返回的处理,主要的启动操作会走到Instrumentation中的execStartActivity()方法中。
<Activity.java>

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);

            ...

        } else {

            ...

        }
    }

  1. Instrumentation主要用于监控和控制系统与应用程序之间的交互,通过Instrumentation类中的execStartActivity()方法获取到ATMS的代理对象,然后调用其中的startActivity()方法来启动新的Activity。获取ATMS引用是一个IBinder类型的引用,ATMS作为服务端处于systemServer进程,与应用进程处于不同的进程,而ATMS继承并实现IActivityTaskManager.Stub相应的方法,是代理对象对应的实现类,所以这里返回的其实是IActivityTaskManager.Stub 的代理对象,通过这个代理对象可以跨进程调用服务端 ATMS的方法。
<Instrumentation.java>

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, String resultWho,
            Intent intent, int requestCode, Bundle options, UserHandle user) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
       
        ... 

        try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getBasePackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                    target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }


<ActivityTaskManagerService.java>

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    ...

}

2. ATMS向AMS发送创建应用进程的过程

经过第一个步骤,Activity的启动流程已经从应用进程走到了系统服务进程中的ATMS中,在ATMS中会进行一些启动Activity的前期处理,其中包括判断应用进程是否创建并运行的处理,如果应用进程未被创建,流程会走到AMS中去创建目标Activity对应的应用进程。

  1. Activity启动的流程从应用程序走到了系统服务端,调用了ATMS中的startActivity()方法来启动新的Activity,startActivity()方法经过多层调用,会走到ATMS中的startActivityAsUser()方法,以特定用户身份来启动一个新的Activity,其中对用户身份做了一些处理,然后通过ActivityStartController的obtainStarter()方法创建一个活动启动器Starter对象,通过链式调用来设置Intent意图等参数,最后调用ActivityStarter的execute()方法执行Activity的启动操作。
<ActivityTaskManagerService.java>

    public final int startActivity(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        assertPackageMatchesCallingUid(callingPackage);
        enforceNotIsolatedCaller("startActivityAsUser");

        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();
    }


  1. ActivityStarter是一个加载启动Activity的控制类,负责在特定的时间和方式下启动一个Activity,ActivityStarter中的execute()作为外部接口,触发整个启动过程,而目标Activity的具体的启动逻辑和记录创建会走到ActivityStarter中的executeRequest()方法中执行;
<ActivityStarter.java>

    int execute() {
        try {

            ...

            int res;
            synchronized (mService.mGlobalLock) {

                ...

                res = executeRequest(mRequest);

                ...

            }
        } finally {
            onExecutionComplete();
        }
    }

    private int executeRequest(Request request) {

        ...

        final ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, callingFeatureId, intent, resolvedType, aInfo,
                mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode,
                request.componentSpecified, voiceSession != null, mSupervisor, checkedOptions,
                sourceRecord);
        mLastStartActivityRecord = r;

        ...

        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);

        if (request.outActivity != null) {
            request.outActivity[0] = mLastStartActivityRecord;
        }

        return mLastStartActivityResult;
    }


  1. ActivityStarter中的executeRequest()方法主要作用是处理启动Activity请求,创建目标Activity对应的ActivityRecord(目标Activity在AMS中的数据结构),将记录存储在任务Task中;之后调用ActivityStarter中的startActivityUnchecked()方法来处理启动新的Activity的前期准备工作;然后走到ActivityStarter中的startActivityInner()方法处理Activity启动模式相关的逻辑;而目标Activity的任务栈Task和Activity进栈处理会调用ActivityStack中的startActivityLocked()方法,主要是将目标Activity的 ActivityRecord 添加到 TaskRecord 栈中,并将对应的 ActivityRecord 提到 TaskRecord 栈中最顶部;
<ActivityStarter.java>

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            mService.deferWindowLayout();
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
            startedActivityStack = handleStartResult(r, result);
            mService.continueWindowLayout();
        }

        postStartActivityProcessing(r, result, startedActivityStack);

        return result;
    }

    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor, restrictedBgActivity);
        computeLaunchingTaskFlags();
        computeSourceStack();

        ...

        mTargetStack.startActivityLocked(mStartActivity, topStack.getTopNonFinishingActivity(),
                newTask, mKeepCurTransition, mOptions);
        if (mDoResume) {

             ...

        else{
                if (mTargetStack.isTopActivityFocusable()
                        && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityInner");
                }
                mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
        }

        ...

        return START_SUCCESS;

  1. 处理完以上操作后, startActivityInner()方法会继续往下执行到if (mDoResume)的else中,调用RootWindowContainer中的resumeFocusedStacksTopActivities()方法,将目标Activity的启动流程交给RootWindowContainer处理。RootWindowContainer 是窗口容器的根容器,管理所有窗口容器的显示, resumeFocusedStacksTopActivities() 方法会恢复对应任务栈顶部的 Activity,使其成为用户界面可见和可交互的状态,然后将启动流程转交给 ActivityStack的resumeTopActivityUncheckedLocked() 方法。
<RootWindowContainer.java>

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

        if (!mStackSupervisor.readyToResume()) {
            return false;
        }

        boolean result = false;
        if (targetStack != null && (targetStack.isTopStackInDisplayArea()
                || getTopDisplayFocusedStack() == targetStack)) {
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        ...

    }

  1. ActivityStack用来管理系统所有 Activity 的各种状态,内部维护了 TaskRecord 的列表,每个 TaskRecord 包含了若干个 ActivityRecord,每个 ActivityRecord 对应了一个 Activity,TaskRecord 相当于在启动模式中的“任务栈”,根据启动模式的不同,在启动 Activity 的时候,会对 TaskRecord 进行不同的操作。ActivityStack中的startActivityLocked()方法已经将对应 Activity 的 ActivityRecord 添加到了栈顶,调用 resumeTopActivityUncheckedLocked() 方法恢复的就是即将启动的栈顶的Activity,然后调用 ActivityStack 的 resumeTopActivityInnerLocked() 方法来做一些判断,调用startPausingLocked() 方法对当前运行的 Activity(发起者 Activity)触发 Pause 动作,调用ActivityStackSupervisor的startSpecificActivity()进一步处理目标 Activity 的启动和恢复过程。
<ActivityStack.java>

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mInResumeTopActivity) {
            return false;
        }

        boolean result = false;
        try {
            mInResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);

            final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }

        return result;
    }

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

        ...

        boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
        }

        ...

        if (next.attachedToProcess()) {

            ...

        } else {

            ...

            mStackSupervisor.startSpecificActivity(next, true, true);
        }

        return true;
    }


  1. ActivityStackSupervisor 是辅助 ATMS 对 Activity 和 Task 进行管理的类,其中 ActivityStackSupervisor 是对 ActivityStack 进行管理的,用 ActivityStack 对 Acitivity 进行状态管理。ActivityStackSupervisor中的startSpecificActivity() 方法会获取 WindowProcessController ,调用其中的hasThread() 方法,通过 判断IApplicationThread 是否已经被赋值来判断应用进程是否已创建并处于运行中,如果已被赋值则调用 ActivityStackSupervisor中的realStartActivityLocked() 方法来处理 Activity 的创建、生命周期的管理、处理与任务和堆栈相关的逻辑等;如果未被赋值,则需要创建应用进程,会调用ATMS的startProcessAsync()方法异步地创建应用进程,启动目标Activity。
<ActivityStackSupervisor.java>

    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(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
            knownToBeDead = true;
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

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

  1. ActivityTaskManagerService中的startProcessAsync()方法的作用就是给AMS发送一条创建新进程的消息,创建目标Activity对应的进程,发送的消息包含启动进程所需要的所有信息。消息传入的第一个参数是一个lambda接口,使用::符号直接链接到目标函数ActivityManagerInternal中的startProcess(),该目标函数是个抽象函数,它的实现在AMS中,到这里就完成了ATMS向AMS发送创建进程消息的过程。
<ActivityTaskManagerService.java>

    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);
            }

            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);
        }
    }

从obtainMessage传入的参数lambda接口链接到目标函数的过程,简要说明就是通过 acquire() 函数获取到一个 PooledRunnable 实例,又通过它的 recycleOnUse() 函数得到一个 PooledLambdaImpl(实现了 PooledLambda 接口)的实例,所以当发送消息调用 sendMessage() 的时候 PooledRunnable 的 run() 方法会得到执行,也即 ActivityManagerInternal的 startProcess() 方法。

<PooledLambda.java>

    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.java>

public interface PooledRunnable
        extends PooledLambda, Runnable, ThrowingRunnable, TraceNameSupplier {
    /** @inheritDoc */
    PooledRunnable recycleOnUse();
}

3. AMS向Zygote进程发送创建应用进程ActivityThread的过程

当目标Activity对应的应用进程未被创建时,系统服务中的ATMS会向AMS发送一条携带进程信息的,创建目标Activity对应的应用进程的消息,启动Activity的流程就走到AMS中,AMS接收到创建应用进程的信息,会再向Zygote进程发送创建应用进程的信息。

  1. ActivityTaskManagerService中的startProcessAsync()方法给AMS发送了一条创建新进程的消息之后,流程走到了ActivityManagerInternal中的startProcess()方法。ActivityManagerInternal是一个抽象类,是Activity管理本地服务接口的,它的实现为 AMS 的内部类 LocalService,在 AMS 启动的过程,通过LocalServices的addService()注册到LocalServices,此类的使用方式与 ServiceManager 相似,不同之处在于,此处注册的服务不是 Binder 对象,并且只能在同一进程(system_server进程)中使用,即ActivityManagerInternal实现类LocalService是system_server进程的本地服务Service,通过本地服务注册到LocalServices中,而AMS也是运行在system_server进程,因此可以直接使用LocalService。ActivityManagerInternal中startProcess()方法在AMS中实现,通过startProcessLocked()方法将创建进程的信息直接传入ProcessList中的startProcessLocked()方法,并返回 ProcessRecord 实例用来记录管理启动进程的信息。
<ActivityManagerInternal.java>

    public abstract void startProcess(String processName, ApplicationInfo info,
            boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);


<ActivityManagerService.java>

        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 */, true /* keepIfLarge */);
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
        }

    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 */);
    }


LocalServices 可以理解为是一个公开缓存池,内部使用 ArrayMap 来存储本地服务对象。system_server 进程中每个服务都可以通过LocalServices中的addService()注册到LocalServices中,需要使用存储的LocalService时通过LocalServices中的getService()获取注册的本地服务。

<ActivityManagerService.java>

    private void start() {

        ...

        LocalServices.addService(ActivityManagerInternal.class, 

        ...

    }

    public final class LocalService extends ActivityManagerInternal {

        ...

    }

  1. 在ProcessList中分别调用了4个startProcessLocked()方法对最初传入的14个参数进行一系列处理,最后根据系统配置,可以同步或异步启动线程,同步启动线程的情况会调用ProcessList中的startProcess()方法来启动一个新进程。
<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;

        ...

        final boolean success =
                startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }

    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, String abiOverride) {
        return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
                false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
                false /* mountExtStorageFull */, abiOverride);
    }

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

            ...

        try{

            ...

            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
                    instructionSet, invokeWith, startTime);
        } catch (RuntimeException e) {

            ...

            return false;
        }
    }

    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) {

        ...

        if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {

            ...

        } else {
            try {
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
            } catch (RuntimeException e) {

                ...

            }
            return app.pid > 0;
        }
    }


  1. ProcessList中的startProcess()方法会创建一个AppZygote对象,孵化出新的进程,然后调用Process的start方法来启动新进程,新Activity对应的进程ActivityThread的创建和启动完成。
<ProcessList.java>

    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 {

            ...

            final Process.ProcessStartResult startResult;
            if (hostingRecord.usesWebviewZygote()) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } else if (hostingRecord.usesAppZygote()) {
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

                // We can't isolate app data and storage data as parent zygote already did that.
                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
                        app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
                        false, false,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                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);
        }
    }

  1. 在ProcessList的startProcess()方法中调用Process的start方法来启动新进程,会进一步调用ZygoteProcess的start()方法,然后走到ZygoteProces中的startViaZygote()方法,通过Zygote来启动进程。
<Process.java>

    public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           int zygotePolicyFlags,
                                           boolean isTopApp,
                                           @Nullable long[] disabledCompatChanges,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   pkgDataInfoMap,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   whitelistedDataInfoMap,
                                           boolean bindMountAppsData,
                                           boolean bindMountAppStorageDirs,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
    }


<ZygoteProcess.java>

    public final Process.ProcessStartResult start(@NonNull final String processClass,
                                                  final String niceName,
                                                  int uid, int gid, @Nullable int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  @Nullable String seInfo,
                                                  @NonNull String abi,
                                                  @Nullable String instructionSet,
                                                  @Nullable String appDataDir,
                                                  @Nullable String invokeWith,
                                                  @Nullable String packageName,
                                                  int zygotePolicyFlags,
                                                  boolean isTopApp,
                                                  @Nullable long[] disabledCompatChanges,
                                                  @Nullable Map<String, Pair<String, Long>>
                                                          pkgDataInfoMap,
                                                  @Nullable Map<String, Pair<String, Long>>
                                                          whitelistedDataInfoMap,
                                                  boolean bindMountAppsData,
                                                  boolean bindMountAppStorageDirs,
                                                  @Nullable String[] zygoteArgs) {
        // TODO (chriswailes): Is there a better place to check this value?
        if (fetchUsapPoolEnabledPropWithMinInterval()) {
            informZygotesOfUsapPoolStatus();
        }

        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }

  1. ZygoteProces中的startViaZygote()方法首先创建字符串列表 argsForZygote,将应用进程的启动参数保存在 argsForZygote 列表中;然后调用ZygoteProcess中的openZygoteSocketIfNeeded()方法打开与Zygote进程的socket连接,如果连接未开启,则尝试开启,可能会产生阻塞和重试;最后调用ZygoteProcess中的zygoteSendArgsAndGetResult()方法,向Zygote进程发送参数列表,启动一个新的子进程并返回子进程的 pid。
<ZygoteProces.java>

    private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                      @Nullable final String niceName,
                                                      final int uid, final int gid,
                                                      @Nullable final int[] gids,
                                                      int runtimeFlags, int mountExternal,
                                                      int targetSdkVersion,
                                                      @Nullable String seInfo,
                                                      @NonNull String abi,
                                                      @Nullable String instructionSet,
                                                      @Nullable String appDataDir,
                                                      @Nullable String invokeWith,
                                                      boolean startChildZygote,
                                                      @Nullable String packageName,
                                                      int zygotePolicyFlags,
                                                      boolean isTopApp,
                                                      @Nullable long[] disabledCompatChanges,
                                                      @Nullable Map<String, Pair<String, Long>>
                                                              pkgDataInfoMap,
                                                      @Nullable Map<String, Pair<String, Long>>
                                                              whitelistedDataInfoMap,
                                                      boolean bindMountAppsData,
                                                      boolean bindMountAppStorageDirs,
                                                      @Nullable String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<>();
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);

        ...

        if (extraArgs != null) {
            Collections.addAll(argsForZygote, extraArgs);
        }

        synchronized(mLock) {
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
    }

  1. ZygoteProcess中的openZygoteSocketIfNeeded()方法,打开与 Zygote 进程的socket连接,如果连接未建立,则尝试调用ZygoteState中的connect()方法创建一个使用给定Zygote socket地址的Socket连接,连接到Zygote的远程服务端,同时创建BufferedWriter和DataInputStream进行参数数据的传输与读取,最后将socket、DataInputStream、BufferedWriter等封装成ZygoteState对象供外部调用。
<ZygoteProcess.java>

    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            attemptConnectionToPrimaryZygote();

            if (primaryZygoteState.matches(abi)) {
                return primaryZygoteState;
            }

            if (mZygoteSecondarySocketAddress != null) {
                // The primary zygote didn't match. Try the secondary.
                attemptConnectionToSecondaryZygote();

                if (secondaryZygoteState.matches(abi)) {
                    return secondaryZygoteState;
                }
            }
        } catch (IOException ioe) {
            throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
        }

        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    }

  1. ZygoteProcess中的zygoteSendArgsAndGetResult()方法最后会调用 ZygoteProcess中的attemptZygoteSendArgsAndGetResult()方法来fork出一个新Launcher进程,该方法使用 ZygoteState中保存的BufferedWriter和DataInputStream来进行 Socket 通信,通过它们进行数据流的传输与读取操作,system_server 进程通过 BufferedWriter 将参数写给Zygote进程的socket的server端,然后阻塞等待Zygote进程的socket返回pid和usingWrapper,最后封装到 ProcessStartResult中。
<ZygoteProcess.java>

    private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {

        ...

        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";

        ...

        return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    }

4. Zygote进程fork进程并启动应用进程

AMS通过socket向Zygote进程发送创建并启动目标Activity对应的ActivityThread进程的消息,启动目标Activity的流程从系统服务走到了Zygote中。

  1. Zygote进程由init进程创建,Zygote启动之后会调用ZygoteInit中的main()方法,首先解析参数,然后创建ZygoteServer实例对象,再调用ZygoteServer中的runSelectLoop() 方法开启 loop 无限循环来监听client socket发来的消息,当接收到创建新进程的socket请求时,立即唤醒并执行相应工作。如果 fork 出系统进程,则加入到列表,然后继续阻塞等待;如果 fork 出子进程,则退出 loop 循环,返回创建的应用子进程,并执行子进程的启动。
<ZygoteInit.java>

    public static void main(String argv[]) {
        ZygoteServer zygoteServer = null;

        ...

        Runnable caller;
        try {

            ...

            zygoteServer = new ZygoteServer(isPrimaryZygote);

            ...

            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            ...
        } finally {
            ...
        }

        if (caller != null) {
            caller.run();
        }
    }


  1. ZygoteServer中的runSelectLoop() 方法会获取 ZygoteProcess中zygoteSendArgsAndGetResult() 方法通过socket传输过来的应用进程的启动参数等,流程如下:

① 开启Loop死循环监听socket事件,没有连接时就阻塞在那里,当有连接到来时唤醒继续往下执行;

② 如果pollIndex==0,说明收到请求连接的事件,请求和Zygote建立socket连接,调用 acceptCommandPeer() 方法创建 ZygoteConnection 对象,并调用 LocalServerSocket的accept() 方法建立 socket 连接,然后添加到监听列表 peers 中,等待与该 socket 有关的命令的到来;

③ 如果pollIndex < usapPoolEventFDIndex ,表示连接的socket上已经发送命令过来,此时调用ZygoteConnection中的processOneCommand() 方法来接收客户端传输过来的应用进程的启动参数,并执行进程创建工作,处理完后,就会断开与客户端的连接,并把用于连接的 socket 从监听列表 peers 中移除。

<ZygoteServer.java>

    Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
        ArrayList<ZygoteConnection> peers = new ArrayList<>();

        socketFDs.add(mZygoteSocket.getFileDescriptor());
        peers.add(null);

        mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;

        while (true) {

            ...

            int pollReturnValue;
            try {
                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            if (pollReturnValue == 0) {

                ...

            } else {
                boolean usapPoolFDRead = false;

                while (--pollIndex >= 0) {
                    if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                        continue;
                    }

                    if (pollIndex == 0) {
                        // Zygote server socket

                        ZygoteConnection newPeer = acceptCommandPeer(abiList);
                        peers.add(newPeer);
                        socketFDs.add(newPeer.getFileDescriptor());

                    } else if (pollIndex < usapPoolEventFDIndex) {
                        // Session socket accepted from the Zygote server socket
                        try {
                            ZygoteConnection connection = peers.get(pollIndex);
                            final Runnable command = connection.processOneCommand(this);

                            if (mIsForkChild) {
                                ...
                            } else {

                                if (command != null) {
                                    throw new IllegalStateException("command != null");
                                }

                                if (connection.isClosedByPeer()) {
                                    connection.closeSocket();
                                    peers.remove(pollIndex);
                                    socketFDs.remove(pollIndex);
                                }
                            }
                        } catch (Exception e) {
                            ...
                        } finally {
                            ...
                        }
                    } else {
                        ...
                    }
                }
            }
        }
    }

    private ZygoteConnection acceptCommandPeer(String abiList) {
        try {
            return createNewConnection(mZygoteSocket.accept(), abiList);
        } catch (IOException ex) {
            throw new RuntimeException(
                    "IOException during accept()", ex);
        }
    }

  1. ZygoteConnection中的processOneCommand()方法用来接收客户端传输过来的应用进程的启动参数,并执行进程创建工作,通过Zygote的readArgumentList方法读取system_server端的socket写入的数据,并将存入字符串数组的数据封装成 ZygoteArguments格式,之后会调用Zygote的forkAndSpecialize()方法来 fork 子进程,并返回创建结果pid,最后调用ZygoteConnection中的handleChildProc()方法初始化应用进程。启动Activity的流程就走到了创建成功的目标Activity对应的应用进程中。
<ZygoteConnection.java>

    Runnable processOneCommand(ZygoteServer zygoteServer) {
        String[] args;

        try {
            args = Zygote.readArgumentList(mSocketReader);
        } catch (IOException ex) {
            throw new IllegalStateException("IOException on command socket", ex);
        }

        ...

        ZygoteArguments parsedArgs = new ZygoteArguments(args);

        ...

        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
                parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);

        try {
            if (pid == 0) {
                zygoteServer.setForkChild();

                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;

                return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
            } else {
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                handleParentProc(pid, serverPipeFd);
                return null;
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }
    }

  1. Zygote中的forkAndSpecialize()方法调用native层的nativeForkAndSpecialize()方法,走到Linux的fork()方法创建进程,设置进程的主线程的name,然后调用CallStaticVoidMethod()方法返回Zygote的callPostForkChildHooks()方法处理 fork 子线程之后的线程池管理等操作,最后返回进程的pid。
<Zogate.java>

    static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
            boolean isTopApp, String[] pkgDataInfoList, String[] whitelistedDataInfoList,
            boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
        ZygoteHooks.preFork();

        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
                pkgDataInfoList, whitelistedDataInfoList, bindMountAppDataDirs,
                bindMountAppStorageDirs);

        ...

        return pid;
    }

  1. fork应用进程成功后就调用ZygoteConnection中的handleChildProc()方法进入应用进程中执行进程的初始化操作,关闭socket连接,设置应用进程name,然后调用ZygoteInit中的zygoteInte()方法来初始化Zygote。
<ZygoteConnection.java>

    private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {

        closeSocket();

        Zygote.setAppProcessName(parsedArgs, TAG);

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        if (parsedArgs.mInvokeWith != null) {
            WrapperInit.execApplication(parsedArgs.mInvokeWith,
                    parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(),
                    pipeFd, parsedArgs.mRemainingArgs);

            throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
        } else {
            if (!isZygote) {
                return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mDisabledCompatChanges,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            } else {
                return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            }
        }
    }

  1. ZygoteInit中的zygoteInte()方法初始化Zygote的流程包括 ①日志流重定向,将系统输出和系统错误重定向到 Android 日志;②进程初始化配置,如设置异常捕获 Handler、时区、重置 LogManager 等;③native 层初始化,打开 /dev/binder 驱动,映射内核的地址空间,创建 binder 线程用于 IPC 通信;④调用RuntimeInit中的applicationInit()方法初始化应用程序,返回创建的 Runnable 对象。
<ZygoteInit.java>

    public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }

  1. RuntimeInit中的applicationInit()方法通过nativeSetExitWithoutCleanup()方法做了一个System.exit()的保护,防止退出进程时发生crash,然后设置targetSDKVersion等参数,最后调用findStaticMain()方法加载ActivityThread类以及方法。
<RuntimeInit.java>

    protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {

        nativeSetExitWithoutCleanup(true);

        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);

        final Arguments args = new Arguments(argv);

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }

  1. RuntimeInit中的findStaticMain()方法通过ClassLoader加载获取目标类ActivityThread,获取其静态main方法,然后封装成MethodAndArgsCaller对象返回到ZygoteInit中main()方法的caller,然后调用MethodAndArgsCaller对象实现的Runable接口中的run()方法,使用invoke反射调用ActivityThread中的main()方法。到此,启动目标Activity的流程回到了应用进程中。
<RuntimeInit.java>

    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        return new MethodAndArgsCaller(m, argv);
    }


    static class MethodAndArgsCaller implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }

六、 应用进程ActivityThread启动Activity的过程

Zygote进程fork出目标Activity对应的应用进程,完成该应用进程的初始化以及应用程序的初始化后,通过反射调用使启动Activity的流程回到了应用进程ActivityThread中,该类是应用初始化类,运行在主线程中,ActivityThread中的main()方法是应用的入口方法。

  1. 应用程序启动时,系统会调用ActivityThread中的主函数main()来创建ActivityThread实例,调用attach()方法将该实例与当前应用程序关联,attach()方法中会使用 Binder 通信跨进程调用到system_server进程中AMS的attachApplication()方法,并将 ApplicationThread作为参数传递过去。
<ActivityThread.java>

    public static void main(String[] args) {

        ...

        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        ...

    }

    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }

            ...
        }
    }

  1. AMS中的attachApplication()方法为应用创建必要的环境,在获取到 pid、uid后继续调用AMS中的attachApplicationLocked()方法。AMS中的attachApplicationLocked()方法负责创建和管理应用的全局状态: ①通过跨进程通信调用应用进程ApplicationThread中的bindApplication()方法创建并绑定 Application;②ProcessRecord会调用makeActive()方法保存应用进程IApplicationThread;③通过 ActivityTaskManagerInternal 本地服务过渡到 ATMS 中的attachApplication()方法来启动根 Activity。
<ActivityManagerService.java >

    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ProcessRecord app;

        ...

        try{

            ...

            if (app.isolatedEntryPoint != null) {
                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
            } else if (instr2 != null) {
                thread.bindApplication(processName, appInfo, providerList,
                        instr2.mClass,
                        profilerInfo, instr2.mArguments,
                        instr2.mWatcher,
                        instr2.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.mDisabledCompatChanges);
            } else {
                thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.mDisabledCompatChanges);
            }
            if (profilerInfo != null) {
                profilerInfo.closeFd();
                profilerInfo = null;
            }

            app.makeActive(thread, mProcessStats);
            ...
        } catch (Exception e) {
            ...
        }

        ...

        if (normalMode) {
            try {
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        ...

        return true;
    }

  1. IApplicationThread中的bindApplication()方法调用的是应用进程中的实现类 ApplicationThread中的bindApplication()方法,方法中通过内部类H发送Handler消息,进程接收到的信息交由H处理,在ActivityThread中的handleMessage()方法中进行消息处理,进而调用到ActivityThread中的handleBindApplication()方法处理应用程序绑定。
<ApplicationThread.java>

        public final void bindApplication(String processName, ApplicationInfo appInfo,
                ProviderInfoList providerList, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, AutofillOptions autofillOptions,
                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {

            ...

            setCoreSettings(coreSettings);

            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            ...
            sendMessage(H.BIND_APPLICATION, data);
        }

        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

                 ...

            }
        }

  1. ActivityThread中的handleBindApplication()方法初始化Android的上下文环境和Application,调用了Application的onCreate()方法。
<ActivityThread.java>

    private void handleBindApplication(AppBindData data) {

        ...

            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
                ...
            }

        ...


  1. 通过 ActivityTaskManagerInternal可以过渡到 ATMS 中的attachApplication()方法绑定WindowProcessController,启动根 Activity。ActivityTaskManagerInternal是一个抽象类,其实现类是 ATMS 的内部类 LocalService,是一个本地服务,AMS中调用 ActivityTaskManagerInternal 的方法,实际上调用的是 ATMS中的实现类LocalService的方法。ATMS 中的attachApplication()方法继续调用RootWindowContainer中的attachApplication()方法,启动流程交给RootWindowContainer处理。
<ActivityTaskManagerInternal.java>

    public abstract boolean attachApplication(WindowProcessController wpc) throws RemoteException;


<ActivityTaskManagerService.java>

        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
                }
                try {
                    return mRootWindowContainer.attachApplication(wpc);
                } finally {
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                }
            }
        }

  1. RootWindowContainer中的attachApplication()方法调用RootWindowContainer中的startActivityForAttachedApplicationIfNeeded()方法,该方法中继续调用 ActivityStackSupervisor中的realStartActivityLocked()方法来真正的启动Activity。
<RootWindowContainer.java>

    boolean attachApplication(WindowProcessController app) throws RemoteException {
        final String processName = app.mName;
        boolean didSomething = false;
        for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
            final DisplayContent display = getChildAt(displayNdx);
            final ActivityStack stack = display.getFocusedStack();
            if (stack == null) {
                continue;
            }

            mTmpRemoteException = null;
            mTmpBoolean = false; // Set to true if an activity was started.
            final PooledFunction c = PooledLambda.obtainFunction(
                    RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
                    PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
            stack.forAllActivities(c);
            c.recycle();
            if (mTmpRemoteException != null) {
                throw mTmpRemoteException;
            }
            didSomething |= mTmpBoolean;
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }

    private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
            WindowProcessController app, ActivityRecord top) {
        if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
                || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
            return false;
        }

        try {
            if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
                    true /*checkConfig*/)) {
                mTmpBoolean = true;
            }
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception in new application when starting activity "
                    + top.intent.getComponent().flattenToShortString(), e);
            mTmpRemoteException = e;
            return true;
        }
        return false;
    }

  1. ActivityStackSupervisor中的realStartActivityLocked()方法①创建了ClientTransaction实例,ClientTransaction是用来处理Activity启动、停止和销毁等事务的类;②ClientTransaction实例添加了 ClientTransactionItem 类型的回调消息,其中参数添加的是LaunchActivityItem实例,LaunchActivityItem 继承自 ClientTransactionItem 抽象类并实现了其中的方法;③获取 ClientLifecycleManager实例,调用其scheduleTransaction()方法去调度转换事务Transaction的执行。
<ActivityStackSupervisor.java>

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

        ...
  
        try {

            ...

            try {

                ...

                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                final DisplayContent dc = r.getDisplay().mDisplayContent;

                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,

                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                        r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);

                ...

            } catch (RemoteException e) {
                ...
            }
        } finally {
            ...
        }

        ...

        return true;
    }

  1. ActivityStackSupervisor中的realStartActivityLocked()方法调用ClientLifecycleManager中的scheduleTransaction()方法来调度转换事务Transaction的执行,scheduleTransaction()方法调用ClientTransaction中的schedule()方法来安排Activity事务的执行,继续走到ClientTransactionHandler中的scheduleTransaction()方法,先对事务进行预处理,然后调用sendMessage向ActivityThread发送消息请求执行该Activity事务。H中的handleMessage()方法中获取传递过来的ClientTransaction,并由事务转换器TransactionExecutor中的execute()方法执行该 ClientTransaction 的转换。
<ClientLifecycleManager.java>

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            transaction.recycle();
        }
    }


<ClientTransaction.java>

    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }


<ClientTransactionHandler.java>

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }


<ActivityThread.java>

        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {

                ...

                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        transaction.recycle();
                    }
                    break;

                ...
            }
        }

  1. TransactionExecutor中的execute()方法执行了ClientTransaction实例添加的,入参是LaunchActivityItem的事务回调executeCallbacks(),然后执行了事务生命周期状态executeLifecycleState()。TransactionExecutor中的executeCallbacks()方法循环遍历回调列表中的所有状态请求,并在适当的时间执行添加的LaunchActivityItem状态请求。
<TransactionExecutor.java>

    public void execute(ClientTransaction transaction) {

        ...

        executeCallbacks(transaction);

        executeLifecycleState(transaction);

        ...
    }

  1. LaunchActivityItem作为启动Activity的消息对象发送到目标对应的ActivityThread中,通过调用 LaunchActivityItem 中的 execute() 方法来实际启动 Activity,而execute()方法通过调用ActivityThread中的handleLaunchActivity()方法来处理Activity的启动;
<LaunchActivityItem.java>

    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client, mAssistToken, mFixedRotationAdjustments);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

  1. ActivityThread中的handleLaunchActivity()方法的作用是处理启动Activity的操作,做一些调用其生命周期方法以及处理布局和显示的操作,Activity实际的启动操作会调用ActivityThread中的performLaunchActivity()方法执行。
<ClientTransactionHandler.java>

    public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent);


<ActivityThread.java>

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {

        ...
  
        final Activity a = performLaunchActivity(r, customIntent);

        ...

        return a;
    }

  1. ActivityThread中的performLaunchActivity()方法启动Activity的步骤如下:

① 调用createBaseContextForActivity()方法创建 ContextImpl 对象;

② 调用Instrumentation中的newActivity()方法加载并新建 Activity,主要通过新建的ClassLoader反射获取Activity实例来加载新建的Activity类;

③ 通过LoadApk中的makeApplication()方法用ClassLoader创建了Application对象;

④ 执行 Activity的attach() 方法将ContextImpl和Activity建立关联;

⑤ 实现了 Window 实例的创建并建立自己和Window的关联,当Window接收到外部输入事件后就可以将事件传递给Activity;

⑥ 调用Instrumentation中的callActivityOnCreate()方法,继续调用 Activity中的performCreate()方法,进而调用Activity中的onCreate()方法完成Activity的创建和启动。

<ActivityThread.java>

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        ...

        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            ...
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            ...

            if (activity != null) {
                ...
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);
                ...
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...
            }
            r.setState(ON_CREATE);
            ...
        }
        return activity;
    }


<LoadApk.java>

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {

        ...

        Application app = null;

        ...

        try {
            final java.lang.ClassLoader cl = getClassLoader();

七、总结

Activity的启动主要是从当前Activity发起请求,经过系统服务处理,创建应用进程,然后初始化应用程序,创建并启动目标Activity的过程:

  1. 当前Activity通过startActivity()传入目标Activity的Intent,然后通过startActivityForResult()获取ATMS的代理对象实现了跨进程调用系统服务进程中ATMS的过程;

  2. ATMS会创建一个Activity启动器ActivityStarter,处理启动Activity的前期操作,将目标Activity移到栈顶,然后判断目标Activity对应的应用进程是否存在,不存在的话ATMS通过lambda接口发送创建应用进程的消息,AMS实现该lambda接口,即AMS接收ATMS发送的创建应用进程的消息;

  3. AMS接收到创建进程的消息,会创建AppZygote对象,通过ZygoteProcess打开AMS与Zygote进程的socket连接,通过socket通信将需要创建的应用进程的信息发送到Zygote进程中;

  4. Zygote进程接收并读取通过socket发来的应用进程信息,通过fork创建应用进程,并初始化该应用进程,然后初始化应用程序,最后通过ClassLoader反射进入应用入口ActivityThread的main()方法;

  5. 应用程序启动会创建ActivityThread实例,将该实例通过attach与当前应用程序关联起来,初始化context和Application,在系统服务中创建ClientTransaction实例来处理Activity事务,然后给ActivityThread发送执行Activity事务的消息,在适当的时间执行ClientTransaction回调的入参传入的LaunchActivityItem请求,实现目标Activity的启动及生命周期管理等操作。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题
图片

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值