知识更新:Android 启动流程之——从系统至App启动流程(基于API 33)

125 阅读24分钟

最近感觉android的启动流程有些遗忘了,打算温习一下,翻了翻源码后发现跟以前记忆中不太一样了,于是上网查了些文章资料等,但也几乎都是些比较旧版本的源码讲解,新版API与旧版部分内容有变动。故重新阅读新版源码梳理一遍,以作笔记。

注:本文目的是把控整体的流程,不作细节深入,仅保留关键代码。

1. 从上电至init进程

电源->Boot ROM->BootLoader->Kernel->swapper进程->init进程

长按Power键上电后,引导芯片开始执行ROM里的预设代码,将引导程序BootLoader加载到RAM中, 开始启动引导程序。引导程序会拉起Kernel内核,在Kernel中会启动swapper进程(swapper进程是Android系统启动的第一个进程)。swapper进程会创建init进程,此时开始进入用户空间。init进程会创建Zygote进程,从此开始进入Java世界,Zygote进程之前都是用c/c++语言编写的,暂不做研究,本文的重点也是在Zygote进程之后的部分

2. Zygote进程至Launcher进程

Zygote译为受精卵,顾名思义该进程是孵化器,是Java进程的鼻祖,所有的Java进程(包括我们的App进程)都是由它fork而来的

2.1. Zygote进程至SystemServer进程

上面说到init进程会创建Zygote进程,入口是ZygoteInit.java的main方法,由c/c++代码调用。在main方法中我们主要关注三件事:

public static void main(String[] argv) {
...
    boolean startSystemServer = false; // 848行
    ...
    // c/c++代码调用main方法时传入的argv参数,第二个元素值为"start-system-server",所以会将startSystemServer变量置为true,后续就会调用forkSystemServer方法。
    for (int i = 1; i < argv.length; i++) {
        if ("start-system-server".equals(argv[i])) { // 853行
            startSystemServer = true;
        } else ...
    }
    ...
    zygoteServer = new ZygoteServer(isPrimaryZygote); //1. 创建ZygoteServer对象
    if (startSystemServer) { // 908行                 //2. fork出SystemServer进程
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
       
        if (r != null) {
            r.run();
            return;
        }
    }
    
    caller = zygoteServer.runSelectLoop(abiList);    //3. Zygote进程开启无限循环等待AMS创建进程的请求
    if (caller != null) {
        caller.run();
    }
}
  1. 创建ZygoteServer对象,其构造方法中会初始化Socket为接收fork进程请求做准备。
  2. 调用forkSystemServer方法fork出SystemServer进程,返回一个Runnable对象,然后调用r.run方法就会执行SystemServer.java的main方法从而进入SystemServer中(为什么调用run方法就会执行main方法下面会说到)。
  3. 开启无限循环等待接收AMS创建进程的请求。

这里可能有人会问:forkSystemServer方法既然返回了Runnable,则r != null成立,main方法就直接return了,代码执行不到3.处,那Zygote进程又是如何开启循环等待接收请求的呢,难道ZygoteInit.main方法会被调用两次,第二次startSystemServer为false不走forkSystemServer方法?

ZygoteInit.main方法并不是被调用两次,这里确实可能有点不好理解,我打个比方:

鸣人正在跟佩恩干架,战斗过程中鸣人用影分身之术创建了一个分身,这个分身会复刻本体施术瞬间的所有状态(包括查克拉的消耗、所受到的伤害、当前时刻的肢体姿势等),分身创建出来后会和本体分成两条线路行动,分身做分身的事,本体做本体的事。

回到代码中,当执行到forkSystemServer方法后,Zyogte进程(本体)fork出了SystemServer进程(分身)就相当于鸣人本体创建了一个分身,那么现在就有两个进程在并行。因为分身会复刻本体的所有状态,所以在分身中,代码也是执行到了forkSystemServer方法等待返回Runnable。本体中的forkSystemServer方法会返回null,所以main方法就不会return,就会执行到3.处,而分身中的forkSystemServer方法会返回一个Runnable对象,后续就会调用r.run并return掉main方法,从此分身就和本体分道扬镳,各自去做各自的事情了。

我们先看forkSystemServer方法是如何创建SystemServer进程的:

private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {
    ...
    pid = Zygote.forkSystemServer( // 770行
        parsedArgs.mUid, parsedArgs.mGid,
        parsedArgs.mGids,
        parsedArgs.mRuntimeFlags,
        null,
        parsedArgs.mPermittedCapabilities,
        parsedArgs.mEffectiveCapabilities);
}

内部是调用了Zygote.forkSystemServer方法,点进Zygote.forkSystemServer方法,内部最终是通过调用native方法来真正fork出SystemServer进程的:

static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    ZygoteHooks.preFork();

    int pid = nativeForkSystemServer( // 479行
            uid, gid, gids, runtimeFlags, rlimits,
            permittedCapabilities, effectiveCapabilities);
    ...
    return pid;
}

private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

在fork出SystemServer进程后对其进行处理:

    //接上面 pid = Zygote.forkSystemServer( // 770行
    /* For child process */
    if (pid == 0) { // fork出来的子进程pid是0
        ...
        return handleSystemServerProcess(parsedArgs); // 788行
    }

上面ZygoteInit.forkSystemServer方法返回值是一个Runnable,就是通过handleSystemServerProcess方法获取的,点进handleSystemServerProcess方法:

private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    ...
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, // 554行
                parsedArgs.mDisabledCompatChanges,
                parsedArgs.mRemainingArgs, cl);
}

继续跟进zygoteInit方法:

public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    ...
    return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
            classLoader);
}

调用了RuntimeInit.applicationInit方法,继续跟进:

protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    ...
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

最终会调用到RuntimeInit.findStaticMain方法,Runnable就是在这个方法里生成的:

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

    try {  //这里className为SystemServer
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        ...

    Method m;
    try {  //通过反射获取到main方法的Method对象
        m = cl.getMethod("main", new Class[] { String[].class }); 
    } catch (NoSuchMethodException ex) {
       ...

    int modifiers = m.getModifiers();
    //检查main方法的修饰符如果不是public和static就抛出异常
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }
    return new MethodAndArgsCaller(m, argv);
}

MethodAndArgsCaller顾名思义就是方法的调用者,也可以理解为存放方法的容器,它是RuntimeInit的静态内部类,实现了Runnable接口:

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

当外部调用其run方法时,即会调用其内部所传入方法的invoke从而执行方法。这里将SystemServer的main方法的Method对象以及参数传入MethodAndArgsCaller中,返回MethodAndArgsCaller实例,这个实例会一直返回至上面的ZygoteInit.java的908行处,随后调用其run方法,就会执行SystemServer的main方法了。至此开始进入SystemServer进程。

2.2. SystemServer进程至Launcher进程

上面说到了执行SystemServer的main方法,先简单介绍一下SystemServer进程:

SystemServer进程顾名思义为系统服务进程,它是由Zygote进程fork而来的,也是Zygote fork的第一个进程,负责启动和管理整个Java Framework层,承载了包括我们常用的ActivityManagerService、WindowManagerService、PackageManagerService等各类上百种系统服务的创建和启动工作。

继续来看main方法:

public static void main(String[] args) { // 648行
    new SystemServer().run();
}

简单明了,仅一行代码,new了一个SystemServer对象并调用其run方法。点进run方法:

private void run() {
    try{
        ...省略一些初始化和准备操作      
        createSystemContext(); // 初始化系统上下文
        ...       
        //创建系统服务管理者,各个系统服务的创建、启动以及其他生命周期事件都由它管理
        mSystemServiceManager = new SystemServiceManager(mSystemContext); 
    }
    ...
    try {
        //启动各系统服务 935行
        startBootstrapServices(t);  //启动引导服务
        startCoreServices(t);       //启动核心服务
        startOtherServices(t);      //启动其他服务
        startApexServices(t);       //启动Apex服务
    }
    ...
    //无限循环等待接收并处理其他线程消息
    Looper.loop()
}

run方法中主要做三件事:1.一些初始化和准备操作 2.启动各系统服务 3.开启无限循环等待接收并处理其他线程消息。

系统服务分为四类(如上代码所示),其中Apex服务是在API 33引入的,在33版本以前只分为上面三类服务。Apex服务是用于系统OTA升级的,简单了解就好,这里不做深入。点进startApexServices简单看一下:

/**
 * Starts system services defined in apexes.
 *
 * <p>Apex services must be the last category of services to start. No other service must be
 * starting after this point. This is to prevent unnecessary stability issues when these apexes
 * are updated outside of OTA; and to avoid breaking dependencies from system into apexes.
 */
private void startApexServices(@NonNull TimingsTraceAndSlog t) { // 3069行
    ...
    List<ApexSystemServiceInfo> services = ApexManager.getInstance().getApexSystemServices();
    for (ApexSystemServiceInfo info : services) {
        String name = info.getName();
        String jarPath = info.getJarPath();
        t.traceBegin("starting " + name);
        if (TextUtils.isEmpty(jarPath)) {
            mSystemServiceManager.startService(name);
        } else {
            mSystemServiceManager.startServiceFromJar(name, jarPath);
        }
        t.traceEnd();
    }

    // make sure no other services are started after this point
    mSystemServiceManager.sealStartedServices();
    ...
}

根据方法注释可知,Apex服务必须是最后启动的服务类别,在此之后不能启动其他服务。方法内部也比较简单,通过ApexManager的getApexSystemServices方法获取Apex服务集合并遍历启动。启动完成后在方法最后调用sealStartedServices(顾名思义,封锁启动服务)方法来禁止再启动其他服务。

简单了解完Apex服务,我们主要来看ActivityManagerService。AMS属于引导服务类别,在startBootstrapServices方法中启动。点进startBootstrapServices方法:

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) { // 1052行
    ...  //启动一些引导服务如:PowerStatsService、DeviceIdentifiersPolicyService等等
    
    //启动ATMS和AMS
    ActivityTaskManagerService atm = mSystemServiceManager.startService( // 1122行
        ActivityTaskManagerService.Lifecycle.class).getService();
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
        mSystemServiceManager, atm);
}

ATMS(ActivityTaskManagerService)是在API 29引入的,目的是分担部分AMS的职责(比如将Activity的启动相关的调用转移到了ATMS中),减轻AMS的负担。AMS中持有ATMS。

启动完引导服务和核心服务,执行到startOtherServices方法,在该方法中启动完其他服务后,会调用AMS的systemReady方法:

private void startOtherServices(@NonNull TimingsTraceAndSlog t) { // 1404行
    ... //启动非常多的其他类型系统服务
    mActivityManagerService.systemReady(() -> { // 2801行
        ...
    }
}

systemReady方法即为Launcher进程的启动入口,从调用此方法开始进行Launcher进程(即Launcher桌面程序,是Zygote孵化的第一个App进程)的启动(Launcher进程的启动过程比较复杂,篇幅原因此处暂不做分析,后面会单独出一篇文章来讲解Launcher进程启动过程),待Launcher进程启动完毕后,Android系统也就启动完成,开始等待用户点击桌面中的应用图标来启动各App进程。

3. 从点击桌面应用图标至App启动

3.1 Activity启动流程

当点击桌面中的应用图标时,实际上启动的是目标应用的入口Activity,会调用Activity的startActivity方法。所以先来看一下Activity的启动流程。

3.1.1 从startActivity至判断目标Activity是否存在进程

我们都知道startActivity方法最终会调用到startActivityForResult方法,所以直接看startActivityForResult方法:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
    ...
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, this, //这里的mMainThread类型是ActivityThread
            intent, requestCode, options);
    if (ar != null) {
        mMainThread.sendActivityResult(
            mToken, mEmbeddedID, requestCode, ar.getResultCode(),
            ar.getResultData());
    }
    ...
}

调用了mInstrumentation.execStartActivity方法。这里涉及到一个类:

Instrumentation

Instrumentation实际上是Android Framework中的一个类,该类并不是专门用于负责Activity启动过程的某些工作的,它的作用简单来说就是能够监控Android系统和应用程序之间的所有交互。Instrumentation会在App启动阶段被初始化,然后将实例保存在ActivityThread对象中。Application的创建、Activity生命周期方法的回调等其他操作,都会经过Instrumentation来完成,会先调用Instrumentation的相应方法。

接着看execStartActivity方法:

public ActivityResult execStartActivity( // 1765行
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    ...
    try {
        intent.migrateExtraStreamToClipData(who);
        intent.prepareToLeaveProcess(who);
        int result = ActivityTaskManager.getService().startActivity(whoThread,
                who.getOpPackageName(), 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;
}

会调用到ActivityTaskManager.getService().startActivity方法。这里就从App进程(这里的App指的是Launcher)进程转到了SystemServer进程。App进程和SystemServer进程间通信使用的是Binder机制,这里ActivityTaskManager.getService()获取到的是ATMS(ActivityTaskManagerService)的代理类对象,startActivity方法实际上也就是调用的ATMS的startActivity方法,所以看ATMS的startActivity方法:

public final int startActivity(some args){
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

很简单,直接调用startActivityAsUser方法,继续跟进:

private int startActivityAsUser(some args){
    ...
    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();
}

发现是调用了getActivityStartController().obtainStarter().execute方法。这里getActivityStartController().obtainStarter()得到的是ActivityStarter类对象,ActivityStarter的主要作用是在启动Activity之前把所有信息都准备全,整合到一个Request(是ActivityStarter中的内部类)中。上面代码中的一堆链式set调用就是将各种信息传入到Request中,然后调用execute方法来执行启动操作。进入execute方法:

int execute() { // 648行
    ...
    int res;
    ...
    res = executeRequest(mRequest); // 702行
    ...
}

可以看到,刚才所说的Request就在这里用到了,调用了executeRequest方法来执行启动请求。继续跟进:

private int executeRequest(Request request) { // 848行
    ...
    final ActivityRecord r = new ActivityRecord.Builder(mService) // 1176行
        .setCaller(callerApp)
        .setLaunchedFromPid(callingPid)
        .setLaunchedFromUid(callingUid)
        .setLaunchedFromPackage(callingPackage)
        .setLaunchedFromFeature(callingFeatureId)
        .setIntent(intent)
        .setResolvedType(resolvedType)
        .setActivityInfo(aInfo)
        .setConfiguration(mService.getGlobalConfiguration())
        .setResultTo(resultRecord)
        .setResultWho(resultWho)
        .setRequestCode(requestCode)
        .setComponentSpecified(request.componentSpecified)
        .setRootVoiceInteraction(voiceSession != null)
        .setActivityOptions(checkedOptions)
        .setSourceRecord(sourceRecord)
        .build();
    ...
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession, // 1216行
        request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
        inTask, inTaskFragment, restrictedBgActivity, intentGrants);
    ...
}

在executeRequest方法中,创建了ActivityRecord r并设置了一堆数据,然后调用了startActivityUnchecked方法,将r传入。 ActivityRecord是Activity组件在 AMS 中的代表,每一个在应用中启动的 Activity,在AMS中都有一个 ActivityRecord 实例与之对应。点进startActivityUnchecked方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,
        TaskFragment inTaskFragment, boolean restrictedBgActivity,
        NeededUriGrants intentGrants) {
    ...
    try {
        ...
        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
            intentGrants);
    }
}

又调用了startActivityInner方法,继续跟进:

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,
        TaskFragment inTaskFragment, boolean restrictedBgActivity,
        NeededUriGrants intentGrants) {
        
    ...
    mRootWindowContainer.resumeFocusedTasksTopActivities( // 1935行
        mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}

这里RootWindowContainerWindowManagerService的主要组成部分之一,它是一个管理窗口的容器,主要作用是管理整个系统中所有窗口的层级关系和布局。而resumeFocusedTasksTopActivities方法顾名思义,作用是恢复所有获取焦点的Task中的栈顶Activity,自然我们要启动的Activity也包含在内,方法参数中的mStartActivity参数即为要启动的Activity。进入resumeFocusedTasksTopActivities方法:

boolean resumeFocusedTasksTopActivities(
        Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
        boolean deferPause) {
    if (!mTaskSupervisor.readyToResume()) {
        return false;
    }

    boolean result = false;
    if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea() || getTopDisplayFocusedRootTask() == targetRootTask)) { // 2260行
        result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                deferPause);
    }
}

这里targetRootTask类型是Task,Task 是一系列 Activity 界面的集合,根据先进后出的栈结构进行管理,我们在描述Activity启动模式时所说的栈就是它。调用了Task的resumeTopActivityUncheckedLocked方法,继续跟进:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
        boolean deferPause) {
    ...
    someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause); //4938行
}

调用了resumeTopActivityInnerLocked方法,继续跟进:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
        boolean deferPause) {
    ...
    final TaskFragment topFragment = topActivity.getTaskFragment();
    resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
    ...
}

TaskFragment是Task的父类,看一下google对它的注释:

A basic container that can be used to contain activities or other TaskFragment, which also able to manage the activity lifecycle and updates the visibilities of the activities in it.

一个基本的容器,可以用来包含活动或其他TaskFragment,也能够管理活动的生命周期和更新活动的可见性。

调用了TaskFragment的resumeTopActivity方法,继续跟进:

final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
        boolean deferPause) {
    ...
    if (next.attachedToProcess()) {
        ...
        mTaskSupervisor.startSpecificActivity(next, true, false); // 1457行
        return true;
    }else{
        ...
        mTaskSupervisor.startSpecificActivity(next, true, true); // 1483行
    }
    return true
}

这个方法比较长,有将近400行,关键在方法的末尾处,判断next.attachedToProcess()的值,这个next类型是ActivityRecord,也就是我们要启动的Activity,判断它是否已经附着到进程上。不管值是否为true,都会调用 mTaskSupervisor.startSpecificActivity方法。mTaskSupervisor的类型是ActivityTaskSupervisor,这个类是在API 31引入的,31之前是ActivityStackSupervisor。这个类里面功能很混乱,俨然是一个垃圾场了。可以看下google对这个类的注释:

// TODO: This class has become a dumping ground. Let's
// - Move things relating to the hierarchy to RootWindowContainer
// - Move things relating to activity life cycles to maybe a new class called ActivityLifeCycler
// - Move interface things to ActivityTaskManagerService.
// - All other little things to other files.
public class ActivityTaskSupervisor implements RecentTasks.Callbacks {...}

可以猜测在后续的版本更新中这个类会被优化甚至取消。这里我们只关注startSpecificActivity方法:

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;
        }
        ...
    }
    ...
    mService.startProcessAsync(r, knownToBeDead, isTop,
            isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
                    : HostingRecord.HOSTING_TYPE_ACTIVITY);
}

终于,经过了so fucking long like shit的方法链调用,终于来到了关键逻辑:判断要启动的Activity的App进程是否存在,如果存在,调用realStartActivityLocked方法启动Activity(热启动或App进程打开其内部Activity),否则调用mService.startProcessAsync方法启动新进程(冷启动)。先打断一下Activity启动流程,我们先把进程搞出来,先来看一下App启动流程。

3.2 App启动流程

我们知道新的App进程是由SystemServer进程通过Socket方式向Zygote进程发送请求,Zygote收到请求后fork出App进程的,那具体过程是怎样的呢?

3.2.1 SystemServer进程(AMS)向Zygote进程发送创建App进程的请求

上面说到冷启动会调用mService.startProcessAsync方法。mService类型是ATMS,又回到了ATMS中,看下startProcessAsync方法:

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);
        }
        // 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);
    } finally {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }
}

这里是一个难点,可能很多人从这里开始就找不到头绪了,因为这里的代码很容易让人去顺着mH.sendMessage方法跟进。如果顺着mH.sendMessage去找的话,会发现无论如何也找不到是如何向Zygote进程发送请求的。这里我们要关注的是PooledLambda.obtainMessage方法的第一个参数:ActivityManagerInternal::startProcess

这里顺便提一下【::】双冒号运算符,可能有些人在Android里没有用过甚至没有见过。这个运算符表示方法引用,可以理解为将一个方法(A)当作参数传入另一个方法(B)中。在对方法A使用方法引用时不会执行方法A,在方法B中根据需要去调用方法A时才会执行。这也就相当于Kotlin中的函数类型参数,在Kotlin中函数的参数类型可以是一个函数。【::】在Android中比较常见的是在设置点击事件的时候,例如:mButton.setOnClickListener(this::onClick);

言归正传,既然对startProcess方法使用了方法引用,说明这个方法肯定会被调用的,那么就看一下这个方法:

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

发现是一个抽象方法,ActivityManagerInternal也是一个抽象类。查找发现ActivityManagerInternal的子类是 AMS的一个内部类LocalService,来看startProcess方法的实现:

public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
        boolean isTop, String hostingType, ComponentName hostingName) {
    ...
    try{ // 17168行
        startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
            new HostingRecord(hostingType, hostingName, isTop),
            ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
            false /* isolated */);
    }
}

调用了AMS的startProcessLocked方法,继续跟进:

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

mProcessList类型是ProcessList,它可以看做是服务于 AMS 的工具类,用于管理进程。mProcessList.startProcessLocked方法里面调用了一下它的重载方法进行过渡,我们直接看最后的重载方法:

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 startUptime, long startElapsedTime) {
    ...
    try { // 1936行
        final Process.ProcessStartResult startResult = startProcess(hostingRecord,
            entryPoint, app,
            uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
            requiredAbi, instructionSet, invokeWith, startUptime);
        ...
    }
}

调用了startProcess方法,继续跟进:

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) {
    ...
    startResult = Process.start(entryPoint,   // 2300行
        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
        isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
        allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
        new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
    ...
}

调用了Process.start方法,继续跟进:

public static ProcessStartResult start(一堆参数) {
    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);
}

里面很简洁,只调用了ZYGOTE_PROCESS.start方法。ZYGOTE_PROCESS是Process类里的成员变量:

public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

继续跟进ZygoteProcess的start方法:

public final Process.ProcessStartResult start(一堆参数){
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
            runtimeFlags, mountExternal, targetSdkVersion, seInfo,
            abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
            packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
            pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,
            bindMountAppStorageDirs, zygoteArgs);
    }
}

调用了startViaZygote方法,继续跟进:

private Process.ProcessStartResult startViaZygote(一堆参数){
    ArrayList<String> argsForZygote = new ArrayList<>();

    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    ...
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                  zygotePolicyFlags,
                                  argsForZygote);
}

在startViaZygote方法中声明了变量ArrayList argsForZygote,这个argsForZygote就是要向Zygote进程发送的创建App进程请求所需要的各种参数信息,下面就会根据startViaZygote方法传入的那一堆参数来向argsForZygote中添加App进程参数信息,添加完成后会将其传入zygoteSendArgsAndGetResult方法,继续跟进:

private Process.ProcessStartResult zygoteSendArgsAndGetResult(){
    ...
    return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}

调用了attemptZygoteSendArgsAndGetResult方法,继续跟进:

private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
        ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
        final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
        final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

        zygoteWriter.write(msgStr);
        zygoteWriter.flush();
        ...
    }
    ...

直到这里,终于结束了,通过ZygoteState中的Socket向Zygote进程发送了消息请求。

3.2.2 Zygote进程接收创建新App进程的请求并fork出新进程

分析完SystemServer进程发送请求,来看看Zygote进程是如何开启循环等待接收请求的。让我们把目光移回2.1章节。2.1处说到ZygoteInit.main方法中主要做了三件事,先前我们分析了前两件,第三件没有分析:

public static void main(String[] argv) {
    Runnable caller;
    ...
    caller = zygoteServer.runSelectLoop(abiList);    //3. Zygote进程开启无限循环等待AMS创建进程的请求
    if (caller != null) {
        caller.run();
    }
}

调用了zygoteServer.runSelectLoop方法开启循环等待请求,点进runSelectLoop方法:

Runnable runSelectLoop(String abiList) {
    ...
    if (pollIndex == 0) { // 539行
        // Zygote server socket
        ZygoteConnection newPeer = acceptCommandPeer(abiList); // 1.
        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);
            boolean multipleForksOK = !isUsapPoolEnabled()
                && ZygoteHooks.isIndefiniteThreadSuspensionSafe();
            final Runnable command =
                connection.processCommand(this, multipleForksOK); // 2.
                
            if (mIsForkChild) {
                if (command == null) {
                    throw new IllegalStateException("command == null");
                }
                return command;     //3.
            }
        }
        ...
    }
}
  1. 通过acceptCommandPeer方法(里面就是new了一个ZygoteConnection对象)获取了ZygoteConnection对象,ZygoteConnection就是最终实际实现循环等待AMS创建进程请求的地方。
  2. 调用了ZygoteConnection的processCommand方法,里面会实际执行循环等待AMS的请求,收到请求就会fork新进程。
  3. 当fork出一个新的App进程后,会将mIsForkChild置为true,同时2.处会返回一个Runnable,将这个Runnable继续向上返回至caller = zygoteServer.runSelectLoop处,然后调用其run方法。这里的caller和上面创建SystemServer进程时返回的Runnable功能一样,实际实现类都是MethodAndArgsCaller,里面放的是进程的入口main方法,创建SystemServers时是SystemServer.main,这里创建App进程则是ActivityThread.main,调用run方法就会执行main方法。这里还要注意的一点是能执行到3.处的是fork出来的新App进程,Zygote进程会一直在2.处processCommand方法里面无限循环,不会跳出processCommand方法。 如果不能理解的话再返回去看看上面的鸣人大战佩恩。

进入processCommand方法:

Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
    ...
    ZygoteArguments parsedArgs;

    try (ZygoteCommandBuffer argBuffer = new ZygoteCommandBuffer(mSocket)) {
      while (true) {
        try {
        parsedArgs = ZygoteArguments.getInstance(argBuffer);
        // Keep argBuffer around, since we need it to fork.
        }
        ...
        //对parsedArgs中的数据进行一系列判断,如果不符合条件就return掉终止循环。当然正常情况下肯定都是符合的。
                                                
        if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
            || !multipleOK || peer.getUid() != Process.SYSTEM_UID) {  // 1.
  
            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.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,
                parsedArgs.mBindMountAppStorageDirs);
            ...
         } else {  // 2.
            ZygoteHooks.preFork();
            Runnable result = Zygote.forkSimpleApps(argBuffer,
                zygoteServer.getZygoteSocketFileDescriptor(),
                peer.getUid(), Zygote.minChildUid(peer), parsedArgs.mNiceName);
            if (result == null) {
                ...
                continue;
            } else {
                //上面ZygoteServer的runSelectLoop方法中mIsForkChild变量就是通过调用下面这个方法置为true的
                zygoteServer.setForkChild();
                Zygote.setAppProcessName(parsedArgs, TAG);  // ??? Necessary?
                return result;
            }
        }
    }
}

这里要说一下在API 33版本开始有较大差异,processCommand方法在旧版本里方法名是processOneCommand,而且方法内部创建App进程使用的是Zygote.forkAndSpecialize方法。而在33版本里一般创建普通App进程走的是2.处else分支,使用的是Zygote.forkSimpleApps方法,只有很特殊的App进程才会使用Zygote.forkAndSpecialize方法。我们暂不做特殊分析,只看Zygote.forkSimpleApps方法。

可以看到方法里声明了一个ZygoteArguments parsedArgs变量,该类里就是要创建的App进程的各种参数信息。然后在try后面括号里声明了ZygoteCommandBuffer argBuffer变量并进行了实例化,传入了一个Socket,这个Socket就是创建ZygoteConnection对象时构造方法里传入的,传入的是ZygoteServer中的Socket,而ZygServer中的Socket就是在文章最上面2.1章节ZygogeInit.main方法中创建ZygoteServer对象时在其构造方法中初始化的。这样在ZygoteCommandBuffer类内部就可以通过Socket来接收消息,下面try里面使用while(true)进行无限循环,收到Socket消息就会通过ZygoteArguments.getInstance(argBuffer)方法转化为parsedArgs,然后根据parsedArgs中的参数创建App进程。

下面就来到了Zygote.forkSimpleApps方法:

static @Nullable Runnable forkSimpleApps(@NonNull ZygoteCommandBuffer argBuffer,
                                         @NonNull FileDescriptor zygoteSocket,
                                         int expectedUid,
                                         int minUid,
                                         @Nullable String firstNiceName) {
    boolean in_child =
            argBuffer.forkRepeatedly(zygoteSocket, expectedUid, minUid, firstNiceName);
    if (in_child) {
        return childMain(argBuffer, /*usapPoolSocket=*/null, /*writePipe=*/null);
    } else {
        return null;
    }
}

先调用了argBuffer.forkRepeatedly方法,得到一个boolean返回值in_child,然后再根据in_child对本方法进行返回。先看一下forkRepeatedly方法:

boolean forkRepeatedly(FileDescriptor zygoteSocket, int expectedUid, int minUid,
                   String firstNiceName) {
    try { // 168行
        return nativeForkRepeatedly(mNativeBuffer, zygoteSocket.getInt$(),
                expectedUid, minUid, firstNiceName);
    } finally {
        Reference.reachabilityFence(mSocket);
        Reference.reachabilityFence(zygoteSocket);
    }
}

里面很简单,调用了nativeForkRepeatedly方法来fork App进程。nativeForkRepeatedly方法是一个native方法,我们就不去关心底层是怎么实现的了,只需要知道fork出进程后,Zyogte进程的nativeForkRepeatedly方法会返回false,fork出的App进程则会返回true。根据返回值向上倒推,新App进程中in_child的值则为true,Zygote进程中in_child的值则为false,回推到如下代码处:

Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
            ...
            Runnable result = Zygote.forkSimpleApps(argBuffer,
                zygoteServer.getZygoteSocketFileDescriptor(),
                peer.getUid(), Zygote.minChildUid(peer), parsedArgs.mNiceName);
            if (result == null) {
                ...
                continue;
            } else {
                // child; result is a Runnable.
                zygoteServer.setForkChild();
                Zygote.setAppProcessName(parsedArgs, TAG);  // ??? Necessary?
                return result;
            }
        }
    }
}

由上述可知forkSimpleApps方法在Zygote进程中result得到的是null,从而执行continue进入下次循环,继续无限循环等待AMS的请求,永远不会跳出processCommand方法;App进程中result得到的是Zygote的childMain方法返回的值,看下childMain方法返回的是什么(根据方法名合理的猜测一下):

private static Runnable childMain(@Nullable ZygoteCommandBuffer argBuffer,
                                  @Nullable LocalServerSocket usapPoolSocket,
                                  FileDescriptor writePipe) {
    ...
    return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
                             args.mDisabledCompatChanges,
                             args.mRemainingArgs,
                             null /* classLoader */);
}

内部调用了ZygoteInit.zygoteInit方法。这个方法是不是看着比较眼熟,没错,在创建SystemServer进程后也是调用了这个方法,最终返回的是一个SystemServer.main方法的包装类MethodAndArgsCaller。类似的,这里App进程中这个方法最终返回的是一个ActivityThread.main方法包装类MethodAndArgsCaller。这个MethodAndArgsCaller会一直向上返回至如下代码处:

public static void main(String[] argv) {
    Runnable caller;
    ...
    caller = zygoteServer.runSelectLoop(abiList);
    if (caller != null) {
        caller.run();
    }
}

赋值给caller,调用了caller.run方法,也就是调用了ActivityThread.main方法。至此App进程就创建完成,开始进入我们平时应用层开发能涉及到的ActivityThread了。

3.2.3 fork出App进程后创建Application

上面说到fork出进程后会调用ActivityThread.main方法,看一下main方法:

public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
    ...
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    ...
    Looper.loop();
}

主要做了两件事:1、准备主线程Looper并开启loop循环 2、创建ActivityThread对象并调用attach方法。 第一件就不多说了,我们都很熟悉。看attach方法里做了什么:

private void attach(boolean system, long startSeq) {
    ...
    final IActivityManager mgr = ActivityManager.getService();
    try {
        mgr.attachApplication(mAppThread, startSeq);
    }
    ...
}

获取了AMS的代理对象,并调用其attachApplication方法将mAppThread传入。mAppThread类型是ApplicationThread,这个方法作用就是让AMS持有ApplicationThread的代理,从而使AMS可以调用ApplicaitonThread的接口来对Activity进行管理。点进attachApplication方法:

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

主要就是调用了attachApplicationLocked方法,继续跟进:

private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
    ...
    thread.bindApplication(processName, appInfo, // 4889行
                        app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
                        providerList, null, profilerInfo, null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.getCompat(), getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.getDisabledCompatChanges(), serializedSystemFontMap,
                        app.getStartElapsedTime(), app.getStartUptime());
    ...
    try { // 4941行
        didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
    }
}

在做了一系列其他工作后,调用了thread.bindApplication方法,thread类型为IApplicationThread,也就是上面传进来的ApplicationThread代理类,所以调用的是ApplicationThread的bindApplication方法。然后后面还调用了mAtmInternal.attachApplication方法,这个我们一会说,先看bindApplication方法:

public final void bindApplication(一堆参数) {
    ...
    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    data.sdkSandboxClientAppVolumeUuid = sdkSandboxClientAppVolumeUuid;
    ...
    sendMessage(H.BIND_APPLICATION, data);
}

创建了AppBindData对象,并设置了许多数据(数据来源就是bindApplication方法的那一堆参数)。AppBindData对象里存放的就是创建Application所需要的东西。然后向H发送了消息。进入H:

class H extends Handler {
    public void handleMessage(Message msg) {
        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;
    }
}

H收到消息后调用了handleBindApplication方法,继续跟进:

private void handleBindApplication(AppBindData data) {
    ...
    Application app;

    try {
        app = data.info.makeApplicationInner(data.restrictedBackupMode, null); // 6746行
        ...
        if (!data.restrictedBackupMode) {
            if (!ArrayUtils.isEmpty(data.providers)) {
                installContentProviders(app, data.providers); // 6770行
            }
        }
        try {
            mInstrumentation.callApplicationOnCreate(app); //6785行
        } 
    }
}

可以看到这里声明了Application app变量,说明开始创建Appliation了。先调用data.info.makeApplicationInner方法获取到app实例,然后将app传入mInstrumentation.callApplicationOnCreate方法。这个方法看名称就知道了,是调用了Application的onCreate方法,也就到了我们经常使用的Application里面。在callApplicationOnCreate之前还有一个installContentProviders方法,根据名字可知该方法作用是初始化ContentProviders,一些第三方库利用ContentProvider进行初始化就是在这里。看下makeApplicationInner方法:

public Application makeApplicationInner(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    return makeApplicationInner(forceDefaultAppClass, instrumentation,
            /* allowDuplicateInstances= */ false);
}

里面调用了它的重载方法,最后一个参数传入的false。根据方法名可以知道这个参数代表是否允许重复实例,这也就解释了为什么正常情况下一个App程序中只有一个Application了。点进makeApplicationInner方法:

private Application makeApplicationInner(boolean forceDefaultAppClass,
        Instrumentation instrumentation, boolean allowDuplicateInstances) {
    if (mApplication != null) {  
        return mApplication;  // 1.
    }
    synchronized (sApplications) {
            final Application cached = sApplications.get(mPackageName);
            if (cached != null) {
                ...
                if (!allowDuplicateInstances) {
                    mApplication = cached;
                    return cached;  // 2.
                }
            }
    }
    Application app = null;
    try{
        ...
        app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
    }
    mApplication = app;
    if (!allowDuplicateInstances) {
        synchronized (sApplications) {
            sApplications.put(mPackageName, app);
        }
    }
    ...
    return app;  // 3.
}

可以看到,返回Application实例分为三步:

  1. 如果mApplication不为null,直接将mApplication返回
  2. 如果mApplication为null,从sApplications(Application缓存池)中根据包名获取Application实例,如果能获取到实例并且不允许重复实例,则将实例返回
  3. 如果从缓存池中获取不到实例,则创建新实例,并将创建出来的实例赋值给mApplication和存入缓存池,这样当下次再调用方法获取Application实例时即可直接返回。

来看mActivityThread.mInstrumentation.newApplication方法是如何创建Application实例的:

public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

getFactory方法获取到的是AppComponentFactory对象,它的作用是控制清单文件中元素的实例化,也就是说Appliaction以及四大组件的实例都是由它负责创建的。点进instantiateApplication方法:

public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
        @NonNull String className)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Application) cl.loadClass(className).newInstance();
}

可以看到是使用反射创建的Appliaction实例。至此Application创建完毕。在newApplication方法中获取到Application实例后,调用了其attach方法,attach方法里面又调用了attachBaseContext方法。至此我们也可以知道ContentProvider初始化的时机是在Application.attachBaseContext之后、Application.onCreate之前,即:Application.attachBaseContext->initContentProvider->Application.onCreate

3.1.2 目标Activity的进程存在,直接启动Activity

分析完App启动流程后,我们再来继续分析Activity启动流程中的进程存在直接启动的情况,接3.1.1小节:

点进realStartActivityLocked方法:

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
    ...
    final ClientTransaction clientTransaction = ClientTransaction.obtain( // 1.
        proc.getThread(), r.token);
    ...
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), // 2.
        System.identityHashCode(r), r.info,
        // TODO: Have this take the merged configuration instead of separate global
        // and override configs.
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
        proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
        results, newIntents, r.takeOptions(), isTransitionForward,
        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
        r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));
    final ActivityLifecycleItem lifecycleItem;
    if (andResume) {
        lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
    clientTransaction.setLifecycleStateRequest(lifecycleItem); // 3.
    mService.getLifecycleManager().scheduleTransaction(clientTransaction); // 4.
}

方法里主要关注4步:

  1. 创建Activity启动事务clientTransaction
  2. 向clientTransaction中添加LaunchActivityItem。LaunchActivityItem就是启动Activity事务项,它是ClientTransactionItem的子类。ClientTransactionItem可以理解为事务项,现在Activity的生命周期是通过事务的方式来管理,每一个生命周期都是一个事务项,例如上面代码中的ResumeActivityItem、PauseActivityItem等,它们都是间接继承自ClientTransactionItem。
  3. 创建ActivityLifecycleItem lifecycleItem,并根据andResume的值对其进行赋值(这里andResume的值是true),然后通过clientTransaction.setLifecycleStateRequest方法将其传入。setLifecycleStateRequest方法作用是设置事务执行后应该处于的生命周期状态,这里传入的是ResumeActivityItem的实力,也就是最终Activity启动完后处于onResume状态。
  4. 提交并执行clientTransaction。其中mService是ATMS,getLifecycleManager方法得到的是ClientLifecycleManager,顾名思义其作用是客户端生命周期管理者(客户端在这里就是Activity)。

跟进scheduleTransaction方法看做了什么:

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    transaction.schedule();
    ...
}

很简单,直接调用了transaction.schedule方法,继续跟进:

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

也很简单,直接调用了mClient.scheduleTransaction方法将自身传入。mClient的类型是IApplicationThread,即ApplicationThread的代理,所以是调用的ApplicationThread的scheduleTransaction方法,继续跟进:

public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

依然很简单,调用的ActivityThread的scheduleTransaction方法。但是在ActivityThread中却搜索不到scheduleTransaction方法,原来这个方法是在ClientTransactionHandler中,ClientTransactionHandler是个抽象类,ActivityThread继承了该类。点进scheduleTransaction方法:

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

调用了sendMessage方法,根据方法名和参数我们很容易联想到是向ActivityThread中的H发送的消息。点进sendMessage方法:

abstract void sendMessage(int what, Object obj);

发现是个抽象方法,刚才说了ClientTransactionHandler是个抽象类,ActivityThread是它的子类,所以这个方法是在ActivityThread类中实现,那么也就说明就是向H发送的消息。我们就直接看H收到EXECUTE_TRANSACTION消息后做了什么:

class H extends Handler {
    ...
    public void handleMessage(Message msg) {
        case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
            mTransactionExecutor.execute(transaction);
            ...
            break;
    }
}

取出从消息中传递过来的ClientTransaction,并传入mTransactionExecutor.execute方法中。mTransactionExecutor类型是TransactionExecutor,顾名思义是事务执行者,负责事务的实际执行工作。又回到了事务系列类中(这一顿在ActivityThread和事务系列类中反复横跳你受得了吗,中指我先比为敬):

public void execute(ClientTransaction transaction) {
    ...
    executeCallbacks(transaction);

    executeLifecycleState(transaction);
}

这两个方法就对应了上面我们分析过的clientTransaction.addCallback(LaunchActivityItem)和clientTransaction.setLifecycleStateRequest(lifecycleItem),我们暂不关心后者,只看executeCallbacks:

public void executeCallbacks(ClientTransaction transaction) {
    ...
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        ...
        item.execute(mTransactionHandler, token, mPendingActions);
    }
}

从事务中取出事务项,这里拿到的就是上面我们add的LaunchActivityItem,所以这里调用的就是LaunchActivityItem的execute,继续跟进:

public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
                client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
                mTaskFragmentToken);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}

创建了ActivityClientRecord r,ActivityClientRecord是ActivityThread的一个内部类,作用是记录真实的活动实例,这个 r 就代表要启动的Activity。然后调用client.handleLaunchActivity方法,刚才说了ClientTransactionHandler类是抽象类,handleLaunchActivity也是个抽象方法,其实现在子类ActivityThread中,如下:

public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    ...
    final Activity a = performLaunchActivity(r, customIntent);
    ...
}

调用了performLaunchActivity,继续跟进:

//Core implementation of activity launch.
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(  // 3569行
                cl, component.getClassName(), r.intent);
        ...
        activity.attach(appContext, this, getInstrumentation(), r.token,  // 3626行
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
                        r.assistToken, r.shareableActivityToken);
        ...
        mInstrumentation.callActivityOnCreate(activity, r.state);  // 3657行
    }
}

这个方法里就是实际执行Activity创建的代码了,看google的注释:activity启动的核心实现。 创建Activity的过程和上面说过的创建Application很类似:先调用mInstrumentation.newActivity方法获取到Activity实例,newActivity方法里面也是获取到AppComponentFactory对象,在AppComponentFactory里通过反射来创建Activity实例;获取到Activity实例后调用其attach方法,attach方法里也是调用了Activity的attachBaseContext方法,不过还做了一些其他工作,比如初始化PhoneWindow等,这些都是后话,在此不再赘述;调用完attach方法后,调用了callActivityOnCreate方法,该方法里调用了Activity的performCreate方法,performCreate方法最终会调用到Activity的onCreate方法,来正式进入我们日常的业务开发阶段。

结束,so fucking long like shit