应用程序进程的启动

697 阅读12分钟

应用程序程序进程的启动可以分为两大步,分别是AMS发送启动应用程序进程请求和Zygote接收请求并创建应用程序,首先来看第一步

时序图如下

在startProcessLocked中主要做了以下几件事

  • 获取要创建的应用程序进程的用户ID(uid)
  • 创建用户组ID(gids)并赋值
  • 指定应用程序进程主线程的类名为android.app.ActivityThread
  • 调用Process.start方法来启动应用程序

Process的start方法直接调用了ZygoteProcess中的start方法,这个ZygoteProcess类则是保持了与Zygote进程的通信状态,他负责与Zygote的socket建立连接并且开启进程(android.os.process)。我们接着看这个类的start方法,它在类中只是调用了这个类的startViaZygote方法,这个方法其实就是构建应用程序的启动参数并且调用该类中的zygoteSendArgsAndGetResult方法,而这个方法的参数又是通过openZygoteSocketIfNeeded提供。这个open方法实际上就是与ZygoteSocket建立连接,然后将参数封装到ZygoteState中,从而在zygoteSendArgsAndGetResult方法中利用构造的参数与socket通信。至此上半场就介绍完了,下半场则是从在Zygote中创建这个进程

下半场的时序图如下

在之前介绍zygote进程创建的时候就提到,创建完成之后,会调用ZygoteServer.runSelectLoop(在ZygoteInit.java的main方法中调用这个方法)来等待AMS请求,我们先来看看这个runSelectLoop方法做了什么 其实就是就是取出一个未处理的connection(也就是上半场我们创建的那个connection),然后调用connection的processOneCommand方法来处理这个连接。 接着看ZygoteConnection中的这个processOneCommand方法,它主要做了一下几件事

  • 获取并封装应用程序进程的启动参数
  • 通过forkAndSpecialize创建当前进程的子进程并返回pid,这里的pid为0,
  • 调用handleChildProc来处理应用程序进程

handleChildProc:这个方法其实就是为子进程做一些前置设置,比如关闭socket连接,创建binder连接池等。它主要做了两件事

  • closeSocket
  • 调用ZygoteInit中的zygoteInit方法

ZygoteInit.zygoteInit:它主要做了两件事

  • 利用zygoteNativeInit方法创建binder连接池
  • 调用RuntimeInit中的applicationInit

RuntimeInit.applicationInit:这个方法其实就构造了需要的参数Arguments,并且调用了findStaticMain(9.0)

findStaticMain:这里会通过反射找到需要执行的类及类中的main方法,这里的类则是在上半场传入的android.app.ActivityThread类,然后将参数和类传递给MethodAndArgsCaller,这个caller就是runnable,在他的run方法中执行传入的类及方法的method.invoke方法。 在9.0的源码中上半场的runSelectLoop是返回一个runnable的,也就是刚才最后的那个MethodAndArgsCaller,在ZygoteInit.java的main方法的最后则会调用这个runnable的run方法,至此新的应用程序进程已经启动,并且新进程的主线程ActivityThread也已经启动完成。

具体流程如下,它与非根activity的启动区别在startSpecificActivityLocked()方法中

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    getLaunchTimeTracker().setLaunchTime(r);

    if (app != null && app.thread != null) {
      ...
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }
    }

    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

在这个方法中首先会获取包含要启动activity的进程信息的ProcessRecord,新启动应用的话,这个值为null,所以启动根activity的话会调用这里的ActivityManagerService中的startProcessLocked这时候如果是方法,而启动非根activity会调用realStartActivityLocked方法。注意这里的字段“activity”它的变量名为hostingType,其中isolated值为false

我们继续看ActivityManagerService中的这个方法

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    ProcessRecord app;
 // 解释1
    if (!isolated) {
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
      ...
    } else {
      
        app = null;
    }

...
   // 解释2
    String hostingNameStr = hostingName != null
            ? hostingName.flattenToShortString() : null;

    if (app == null) {
        ...
    } else {
        // If this is a new package in the process, add the package to the list
        app.addPackage(info.packageName, info.versionCode, mProcessStats);
        checkTime(startTime, "startProcess: added package to existing proc");
    }

  ...

    checkTime(startTime, "startProcess: stepping in to startProcess");
 // 解释3
    final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
    checkTime(startTime, "startProcess: done starting proc!");
    return success ? app : null;
}

这里的解释1:很好理解因为上面传递的参数为false,所以会用getProcessRecordLocked来获取一个ProcessRecord对象。然后会处理一下这个hostingType,然后会调用解释3处的startProcessLocked方法,并且传入构造好的参数,我们继续看

private final boolean startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
...

    try {
        try {
            final int userId = UserHandle.getUserId(app.uid);
            AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }

        int uid = app.uid;
        int[] gids = null;
        int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
        if (!app.isolated) {
            int[] permGids = null;
            try {
                checkTime(startTime, "startProcess: getting gids from package manager");
                final IPackageManager pm = AppGlobals.getPackageManager();
                permGids = pm.getPackageGids(app.info.packageName,
                        MATCH_DEBUG_TRIAGED_MISSING, app.userId);
                StorageManagerInternal storageManagerInternal = LocalServices.getService(
                        StorageManagerInternal.class);
                mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
                        app.info.packageName);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }

            /*
             * Add shared application and profile GIDs so applications can share some
             * resources like shared libraries and access user-wide resources
             */
            if (ArrayUtils.isEmpty(permGids)) {
                gids = new int[3];
            } else {
                gids = new int[permGids.length + 3];
                System.arraycopy(permGids, 0, gids, 3, permGids.length);
            }
            gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
            gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
            gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));

            // Replace any invalid GIDs
            if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
            if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
        }
        checkTime(startTime, "startProcess: building args");
...
        final String seInfo = app.info.seInfo
                + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
        // Start the process.  It will either succeed and return a result containing
        // the PID of the new process, or else throw a RuntimeException.
//解释1
        final String entryPoint = "android.app.ActivityThread";

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

可以看到这里其实就是进一步的构造创建进程所需要的参数比如gids等,这里需要注意的是解释1处传递的entryPoint,它是“android.app.ActivityThread”,我们继续跟踪代码

private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    app.pendingStart = true;
    app.killedByAm = false;
    app.removed = false;
    app.killed = false;
    final long startSeq = app.startSeq = ++mProcStartSeqCounter;
    app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
//解释1
    if (mConstants.FLAG_PROCESS_START_ASYNC) {
        if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
                "Posting procStart msg for " + app.toShortString());
        mProcStartHandler.post(() -> {
            try {
                synchronized (ActivityManagerService.this) {
                    final String reason = isProcStartValidLocked(app, startSeq);
                    if (reason != null) {
                        Slog.w(TAG_PROCESSES, app + " not valid anymore,"
                                + " don't start process, " + reason);
                        app.pendingStart = false;
                        return;
                    }
                    app.usingWrapper = invokeWith != null
                            || SystemProperties.get("wrap." + app.processName) != null;
                    mPendingStarts.put(startSeq, app);
                }
//解释2
                final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
                        app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
                        requiredAbi, instructionSet, invokeWith, app.startTime);
                synchronized (ActivityManagerService.this) {
                    handleProcessStartedLocked(app, startResult, startSeq);
                }
            }
             ...
        });
        return true;
    } else {
       ...
    }
}

这里其实最重要就两个地方,解释1处的常量默认为true所以不会走else分支,最后会调用解释2处的startProcess方法来启动进程

private ProcessStartResult startProcess(String hostingType, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    try {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                app.processName);
        checkTime(startTime, "startProcess: asking zygote to start proc");
        final ProcessStartResult startResult;
//解释1
        if (hostingType.equals("webview_service")) {
            startResult = startWebView(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, null,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        } else {
//解释2
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        }
        checkTime(startTime, "startProcess: returned from zygote!");
        return startResult;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

这里的解释1就是根据hostingType来判断执行的方法,因为我们之前说过传的是“activity”,虽然在中途进行过修改,但肯定不是“webview_service”,所以这里会执行else中的逻辑,也就是调用Process.start方法,这是android.os.Process中的方法

public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int runtimeFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String invokeWith,
                              String[] zygoteArgs) {
    return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}

需要注意的是这里的第一个参数processClass,它是被用作进程主入口的class,上一步传来的值为entryPoint,就是“android.app.ActivityThread”。这里调用的是zygoteProcess的start方法,而这个zygoteProcess是定义在Process类中的静态常量,其定义如下

/**
 * @hide for internal use only.
 */
public static final String ZYGOTE_SOCKET = "zygote";

/**
 * @hide for internal use only.
 */
public static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary";
public static final ZygoteProcess zygoteProcess =
        new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);

这个ZygoteProcess是用来维持与Zygote进程进行通信状态的。我们看看它的构造方法做了什么

/**
 * The name of the socket used to communicate with the primary zygote.
 */
private final LocalSocketAddress mSocket;

/**
 * The name of the secondary (alternate ABI) zygote socket.
 */
private final LocalSocketAddress mSecondarySocket;

public ZygoteProcess(String primarySocket, String secondarySocket) {
    this(new LocalSocketAddress(primarySocket, LocalSocketAddress.Namespace.RESERVED),
            new LocalSocketAddress(secondarySocket, LocalSocketAddress.Namespace.RESERVED));
}

public ZygoteProcess(LocalSocketAddress primarySocket, LocalSocketAddress secondarySocket) {
    mSocket = primarySocket;
    mSecondarySocket = secondarySocket;
}

可以看到就是创建了两个socket,一个名字为“zygote”,一个名为“zygote_secondary”。我们继续往下看这个start方法

public final Process.ProcessStartResult start(final String processClass,
                                              final String niceName,
                                              int uid, int gid, int[] gids,
                                              int runtimeFlags, int mountExternal,
                                              int targetSdkVersion,
                                              String seInfo,
                                              String abi,
                                              String instructionSet,
                                              String appDataDir,
                                              String invokeWith,
                                              String[] zygoteArgs) {
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
                zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
        Log.e(LOG_TAG,
                "Starting VM process through Zygote failed");
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
    }
}

其实就是调用自身的startViaZygote方法

private Process.ProcessStartResult startViaZygote(final String processClass,
                                                  final String niceName,
                                                  final int uid, final int gid,
                                                  final int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  String seInfo,
                                                  String abi,
                                                  String instructionSet,
                                                  String appDataDir,
                                                  String invokeWith,
                                                  boolean startChildZygote,
                                                  String[] extraArgs)
                                                  throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<String>();

    // --runtime-args, --setuid=, --setgid=,
    // and --setgroups= must go first
    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    argsForZygote.add("--setgid=" + gid);
    argsForZygote.add("--runtime-flags=" + runtimeFlags);
    if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
        argsForZygote.add("--mount-external-default");
    } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
        argsForZygote.add("--mount-external-read");
    } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
        argsForZygote.add("--mount-external-write");
    }
    argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

    // --setgroups is a comma-separated list
    if (gids != null && gids.length > 0) {
        StringBuilder sb = new StringBuilder();
        sb.append("--setgroups=");

        int sz = gids.length;
        for (int i = 0; i < sz; i++) {
            if (i != 0) {
                sb.append(',');
            }
            sb.append(gids[i]);
        }

        argsForZygote.add(sb.toString());
    }

    if (niceName != null) {
        argsForZygote.add("--nice-name=" + niceName);
    }

    if (seInfo != null) {
        argsForZygote.add("--seinfo=" + seInfo);
    }

    if (instructionSet != null) {
        argsForZygote.add("--instruction-set=" + instructionSet);
    }

    if (appDataDir != null) {
        argsForZygote.add("--app-data-dir=" + appDataDir);
    }

    if (invokeWith != null) {
        argsForZygote.add("--invoke-with");
        argsForZygote.add(invokeWith);
    }

    if (startChildZygote) {
        argsForZygote.add("--start-child-zygote");
    }

    argsForZygote.add(processClass);

    if (extraArgs != null) {
        for (String arg : extraArgs) {
            argsForZygote.add(arg);
        }
    }

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

这里首先会构造创建进程的参数比如"--setuid--"等,然后会调用zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);方法,这个方法中又包含了openZygoteSocketIfNeeded(abi)方法,我们首先看这个方法

private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        try {
// 注释1
            primaryZygoteState = ZygoteState.connect(mSocket);
        } catch (IOException ioe) {
            throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
        }
        maybeSetApiBlacklistExemptions(primaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
    }
    if (primaryZygoteState.matches(abi)) {
        return primaryZygoteState;
    }

    if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
        try {
            secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
        } catch (IOException ioe) {
            throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
        }
        maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
    }

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

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

这里的primaryZygoteState则代表的是与值为“zygote”的socket建立连接后的状态信息,所以注释1则是通过connect方法来建立与Zygote进程中的socket进行连接。如果primaryZygoteState与应用程序进程所需的ABI不匹配才会使用secondary。这里就不介绍了。接着看zygoteSendArgsAndGetResult方法

private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args)
        throws ZygoteStartFailedEx {
    try {
        // Throw early if any of the arguments are malformed. This means we can
        // avoid writing a partial response to the zygote.
        int sz = args.size();
        for (int i = 0; i < sz; i++) {
            if (args.get(i).indexOf('\n') >= 0) {
                throw new ZygoteStartFailedEx("embedded newlines not allowed");
            }
        }

        /**
         * See com.android.internal.os.SystemZygoteInit.readArgumentList()
         * Presently the wire format to the zygote process is:
         * a) a count of arguments (argc, in essence)
         * b) a number of newline-separated argument strings equal to count
         *
         * After the zygote process reads these it will write the pid of
         * the child or -1 on failure, followed by boolean to
         * indicate whether a wrapper process was used.
         */
        final BufferedWriter writer = zygoteState.writer;
        final DataInputStream inputStream = zygoteState.inputStream;

        writer.write(Integer.toString(args.size()));
        writer.newLine();

        for (int i = 0; i < sz; i++) {
            String arg = args.get(i);
            writer.write(arg);
            writer.newLine();
        }

        writer.flush();

        // Should there be a timeout on this?
        Process.ProcessStartResult result = new Process.ProcessStartResult();

        // Always read the entire result from the input stream to avoid leaving
        // bytes in the stream for future process starts to accidentally stumble
        // upon.
        result.pid = inputStream.readInt();
        result.usingWrapper = inputStream.readBoolean();

        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }
        return result;
    } catch (IOException ex) {
        zygoteState.close();
        throw new ZygoteStartFailedEx(ex);
    }
}

其实就是将argsForZygote参数写入ZygoteState中,并且把这个state写入socket中,至此向Zygote发送请求的过程就结束了,我们继续看zygote接收到请求的过程。 这个过程则是在ZygoteInit中的main方法中的runSelectLoop方法实现的,因为在main方法中创建了一个名为“zygote”的socket。

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

    fds.add(mServerSocket.getFileDescriptor());
    peers.add(null);

    while (true) {
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        for (int i = 0; i < pollFds.length; ++i) {
            pollFds[i] = new StructPollfd();
            pollFds[i].fd = fds.get(i);
            pollFds[i].events = (short) POLLIN;
        }
        try {
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
            throw new RuntimeException("poll failed", ex);
        }
        for (int i = pollFds.length - 1; i >= 0; --i) {
            if ((pollFds[i].revents & POLLIN) == 0) {
                continue;
            }

            if (i == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                try {
 // 解释1
                    ZygoteConnection connection = peers.get(i);
                    final Runnable command = connection.processOneCommand(this);

                 ..
                        return command;
                    } ...
             
}

当有AMS发送请求时应为这里的fds肯定不为0,所以代码会执行到解释1处。这里会取出这个connection并且调用它的processOneCommand方法

Runnable processOneCommand(ZygoteServer zygoteServer) {
...
applyInvokeWithSystemProperty(parsedArgs);
...
    fd = zygoteServer.getServerSocketFileDescriptor();

    if (fd != null) {
        fdsToClose[1] = fd.getInt$();
    }

    fd = null;

 // 解释1
    pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
            parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
            parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
            parsedArgs.instructionSet, parsedArgs.appDataDir);

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

            zygoteServer.closeServerSocket();
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
 // 解释2
            return handleChildProc(parsedArgs, descriptors, childPipeFd,
                    parsedArgs.startChildZygote);
        } else {
            // In the parent. A pid < 0 indicates a failure and will be handled in
            // handleParentProc.
            IoUtils.closeQuietly(childPipeFd);
            childPipeFd = null;
            handleParentProc(pid, descriptors, serverPipeFd);
            return null;
        }
    } finally {
        IoUtils.closeQuietly(childPipeFd);
        IoUtils.closeQuietly(serverPipeFd);
    }
}

这里首先会构造一些参数,比如开头的applyInvokeWithSystemProperty会将invokeWith参数置为null。然后调用解释1处的forkAndSpecialize方法来创建一个子进程,如果创建成功的话则其pid为0,并且关闭此次socket连接。接着调用handleChildProc方法(运行在新的进程及应用程序进程中)

private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
        FileDescriptor pipeFd, boolean isZygote) {
 
...
    if (parsedArgs.invokeWith != null) {
      ...
    } else {
        if (!isZygote) {
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                    null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
                    parsedArgs.remainingArgs, null /* classLoader */);
        }
    }
}

这里的invokeWith为null所以会执行else中的逻辑,而且isZygote也为false(之前构造创建进程的args),所以为执行zygoteInit方法,这之后就跟Zygote启动时这个方法的后续调用流程是一样的,只不过这里最终调用的是android.app.ActivityThread中的main方法。我们来看看这个main方法

public static void main(String[] args) {
  ...
    Process.setArgV0("<pre-initialized>");
 // 解释1
    Looper.prepareMainLooper();

...
 // 解释2
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
 // 解释3
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

  ...
    Looper.loop();
...
}

可以看到其实就是做了四件事,解释1处的创建主线程的Looper,解释2处的创建ActivityThread类,解释3处的创建主线程handler,最后loop方法开始工作。我们刚才明明是启动一个activity,但是这里却新建了一个进程,那么activity在哪儿启动的呢,我们接着看这里被忽视的方法attach方法,我们来看看他是做什么的。

private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
       ...
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
       // 解释1
  final IActivityManager mgr = ActivityManager.getService();
        try {
        // 解释2
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ...
    } else {
    ...
    }
    ...
}

我们上一步中传递过来的system参数为false。所以这里会执行if中的语句,并且在解释1处获取了ActivityManagerService,在解释2处调用它的attachApplication方法,我们就接着看看这个方法

public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}

其实就是接着调用 attachApplicationLocked(thread, callingPid, callingUid, startSeq)方法

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {

  ...

    // See if the top visible activity is waiting to run in this process...
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
...
    return true;
}

这里的模式为normal,所以会执行if中的mStackSupervisor.attachApplicationLocked方法

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
        for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = display.getChildAt(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);
                if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName)) {
                    try {
 			//解释1
                        if (realStartActivityLocked(activity, app,
                                top == activity /* andResume */, true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                                + top.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    return didSomething;
}

其实这里只看解释1处的代码就能明白,它调用了realStartActivityLocked方法,这就与开篇分析的启动非根activity(进程未创建)与根activity的区别不谋而合了。这里进程已经启动了,所以就跟非根activity的启动一样调用了realStartActivityLocked方法,当然之后的逻辑也一样,这里就不在赘述了。