Android14 - 应用程序进程的启动过程总结分析

337 阅读11分钟

Android系统的启动主要分为几个步骤:swapper -> init -> zygote -> systemserver -> launcher,这些步骤都大致分析了一下,系统启动后,接下来应用程序是如何启动的?启动一个应用程序首先要保证应用程序的进程已经被启动了。

AMS在启动应用程序时,会检查这个应用程序需要的应用程序进程是否存在,不存在就会先去请求Zygote进程启动需要启动的应用程序进程。

启动应用程序可分为两部分来看:1.AMS发送启动应用程序进程请求 2.Zygote收到请求并创建应用程序进程

环境参数:

  • android-14.0.0_r27
  • Ubuntu 22.04.5 LTS

在线源码网址:xrefandroid

Launcher启动过程

AMS发送启动应用程序进程请求

AMS想要启动应用程序进程,首先是需要向Zygote进程发送创建应用程序进程的请求,其入口点在AMS调用startProcessLocked方法:

@frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
        boolean isolated) {
    return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
            hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
            false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
            null /* sdkSandboxClientAppPackage */,
            null /* ABI override */, null /* entryPoint */,
            null /* entryPointArgs */, null /* crashHandler */);
}

会自动进入到ProcessList的startProcessLocked方法中去,此函数重载,需要根据上下文参数确认是哪一个函数:

@frameworks/base/services/core/java/com/android/server/am/ProcessList.java
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
        int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
        String abiOverride) {
    ...
    try {
        final int userId = UserHandle.getUserId(app.uid);
        try {
            AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        }
        //获取要创建的应用程序进程的用户ID
        int uid = app.uid;
        //对gids进程创建赋值
        int[] gids = null;
        int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
        boolean externalStorageAccess = false;
        if (!app.isolated) {
            int[] permGids = null;
            ...

            gids = computeGidsForProcess(mountExternal, uid, permGids, externalStorageAccess);
        }
        app.setMountMode(mountExternal);
        ...
        String seInfo = updateSeInfo(app);

        final String entryPoint = "android.app.ActivityThread";

        return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
                instructionSet, invokeWith, startUptime, startElapsedTime);
    } catch (RuntimeException e) {
        ...
        mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                false, false, true, false, false, app.userId, "start failure");
        return false;
    }
}

跳转到了另外一个重载函数中去了,同时其中有一个参数entryPoint,其值为android.app.ActivityThread需要注意:

@frameworks/base/services/core/java/com/android/server/am/ProcessList.java
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) {
    ...
    if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
        //handleProcessStart中,也会走到startProcess方法中去
        mService.mProcStartHandler.post(() -> handleProcessStart(
                app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
                requiredAbi, instructionSet, invokeWith, startSeq));
        return true;
    } else {
        try {
            //去启动应用程序进程,返回Process.ProcessStartResult
            final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                    entryPoint, app,
                    uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                    requiredAbi, instructionSet, invokeWith, startUptime);
            handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                    startSeq, false);
        }
        ...
        return app.getPid() > 0;
    }
}

private void handleProcessStart(final ProcessRecord app, final String entryPoint,
        final int[] gids, final int runtimeFlags, int zygotePolicyFlags,
        final int mountExternal, final String requiredAbi, final String instructionSet,
        final String invokeWith, final long startSeq) {
    final Runnable startRunnable = () -> {
        try {
            final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(),
                    entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags,
                    mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith,
                    app.getStartTime());

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

startProcessLocked函数最后都会走到startProcess函数中去:

@frameworks/base/services/core/java/com/android/server/am/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 {
        ...
        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.getDisabledCompatChanges(),
                    new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
        } 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.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,
                    false, false,
                    new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
        } else {
            regularZygote = true;
            //启动应用程序进程
            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.getDisabledCompatChanges(), pkgDataInfoMap,
                    allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                    new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});
            // By now the process group should have been created by zygote.
            app.mProcessGroupCreated = true;
        }
        ...
        return startResult;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
}

将进程用户ID,用户组ID,entryPoint等参数传进Process的start方法中去,其中entryPoint为android.app.ActivityThread,是应用程序进程主线程的类名:

@frameworks/base/core/java/android/os/Process.java

public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

/**
* @param processClass The class to use as the process's main entry point.
*/
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);
    }

在Process的start方法中,只调用了ZygoteProcess的start方法,其中ZygoteProcess是用于保持与Zygote进程的通信状态:

@frameworks/base/core/java/android/os/ZygoteProcess.java#start
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>>
                                                      allowlistedDataInfoList,
                                              boolean bindMountAppsData,
                                              boolean bindMountAppStorageDirs,
                                              @Nullable String[] zygoteArgs) {
    

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

在ZygoteProcess的start方法中,调用了startViaZygote方法:

@frameworks/base/core/java/android/os/ZygoteProcess.java#startViaZygote
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>>
                                                          allowlistedDataInfoList,
                                                  boolean bindMountAppsData,
                                                  boolean bindMountAppStorageDirs,
                                                  @Nullable String[] extraArgs)
                                                  throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<>();

    // --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_INSTALLER) {
        argsForZygote.add("--mount-external-installer");
    } else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
        argsForZygote.add("--mount-external-pass-through");
    } else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
        argsForZygote.add("--mount-external-android-writable");
    }

    argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
    //全是构建argsForZygote参数,省略了。
    ...
    //"android.app.ActivityThread"放入数组
    argsForZygote.add(processClass);

    synchronized(mLock) {
        // The USAP pool can not be used if the application will not use the systems graphics
        // driver.  If that driver is requested use the Zygote application start path.
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                          zygotePolicyFlags,
                                          argsForZygote);
    }
}

首先创建了一个字符串列表argsForZygote, 然后向列表添加了很多参数,最后调用zygoteSendArgsAndGetResult方法,其中一个参数是openZygoteSocketIfNeeded函数的返回值:

@frameworks/base/core/java/android/os/ZygoteProcess.java#zygoteSendArgsAndGetResult
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
        throws ZygoteStartFailedEx {
    // Throw early if any of the arguments are malformed. This means we can
    // avoid writing a partial response to the zygote.
    for (String arg : args) {
        // Making two indexOf calls here is faster than running a manually fused loop due
        // to the fact that indexOf is an optimized intrinsic.
        if (arg.indexOf('\n') >= 0) {
            throw new ZygoteStartFailedEx("Embedded newlines not allowed");
        } else if (arg.indexOf('\r') >= 0) {
            throw new ZygoteStartFailedEx("Embedded carriage returns not allowed");
        }
    }

    String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
    if (shouldAttemptUsapLaunch(zygotePolicyFlags, args)) {
        try {
            return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
        }
        ...
    }
    return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}

将启动参数args转化为了字符串后,会根据判断进入对应函数,主要都是将启动参数写入zygoteState中去,最后再转化为Process.ProcessStartResult:

@frameworks/base/core/java/android/os/ZygoteProcess.java
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();
        // Always read the entire result from the input stream to avoid leaving
        // bytes in the stream for future process starts to accidentally stumble
        // upon.
        Process.ProcessStartResult result = new Process.ProcessStartResult();
        result.pid = zygoteInputStream.readInt();
        result.usingWrapper = zygoteInputStream.readBoolean();
        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }
        return result;
    } catch (IOException ex) {
        zygoteState.close();
        Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                + ex.toString());
        throw new ZygoteStartFailedEx(ex);
    }
}

private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
        ZygoteState zygoteState, String msgStr)
        throws ZygoteStartFailedEx, IOException {
    try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
        final BufferedWriter usapWriter =
                new BufferedWriter(
                        new OutputStreamWriter(usapSessionSocket.getOutputStream()),
                        Zygote.SOCKET_BUFFER_SIZE);
        final DataInputStream usapReader =
                new DataInputStream(usapSessionSocket.getInputStream());

        usapWriter.write(msgStr);
        usapWriter.flush();

        Process.ProcessStartResult result = new Process.ProcessStartResult();
        result.pid = usapReader.readInt();
        // USAPs can't be used to spawn processes that need wrappers.
        result.usingWrapper = false;

        if (result.pid >= 0) {
            return result;
        } else {
            throw new ZygoteStartFailedEx("USAP specialization failed");
        }
    }
}

而zygoteState参数是由上面openZygoteSocketIfNeeded函数返回的:

@frameworks/base/core/java/android/os/ZygoteProcess.java#openZygoteSocketIfNeeded
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    try {
        //与zygote进程建立socket连接
        attemptConnectionToPrimaryZygote();
        //连接zygote主模式返回的ZygoteState是否与启动应用程序进程所需要的ABI匹配
        if (primaryZygoteState.matches(abi)) {
            return primaryZygoteState;
        }
        //如果上面的不匹配,则尝试连接zygote的辅模式
        if (mZygoteSecondarySocketAddress != null) {
            // The primary zygote didn't match. Try the secondary.
            attemptConnectionToSecondaryZygote();
           //连接zygote辅模式返回的ZygoteState是否与启动应用程序进程所需要的ABI匹配
            if (secondaryZygoteState.matches(abi)) {
                return secondaryZygoteState;
            }
        }
    } catch (IOException ioe) {
        throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
    }

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

会先用主模式去连接zygote,如果不符合要求,再使用辅模式去连接,两种连接方式使用的socket是不一样的:

/**
 * Creates a ZygoteState for the primary zygote if it doesn't exist or has been disconnected.
 */
@GuardedBy("mLock")
private void attemptConnectionToPrimaryZygote() throws IOException {
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        //使用mZygoteSocketAddress,用的是Zygote.PRIMARY_SOCKET_NAME
        primaryZygoteState =
                ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);

        maybeSetApiDenylistExemptions(primaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
    }
}

/**
 * Creates a ZygoteState for the secondary zygote if it doesn't exist or has been disconnected.
 */
@GuardedBy("mLock")
private void attemptConnectionToSecondaryZygote() throws IOException {
    if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
        //使用mZygoteSecondarySocketAddress,用的是Zygote.SECONDARY_SOCKET_NAME
        secondaryZygoteState =
                ZygoteState.connect(mZygoteSecondarySocketAddress,
                        mUsapPoolSecondarySocketAddress);

        maybeSetApiDenylistExemptions(secondaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
    }
}


public ZygoteProcess() {
    mZygoteSocketAddress =
            new LocalSocketAddress(Zygote.PRIMARY_SOCKET_NAME,
                                   LocalSocketAddress.Namespace.RESERVED);
    mZygoteSecondarySocketAddress =
            new LocalSocketAddress(Zygote.SECONDARY_SOCKET_NAME,
                                   LocalSocketAddress.Namespace.RESERVED);
    ...                               
}

可以看出主模式去连接zygote的socket用的是Zygote.PRIMARY_SOCKET_NAME,辅模式用的是Zygote.SECONDARY_SOCKET_NAME。

在zygote进程启动过程中,会去创建socket的服务端,具体是在zygote刚进Java框架层,在ZygoteInit的main方法中通过创建ZygoteServer对象去管理socket:

@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#main
public static void main(String[] argv) {
    ZygoteServer zygoteServer = null;
    ...
    zygoteServer = new ZygoteServer(isPrimaryZygote);
    ...
    //进入循环读取数据
    Runnable caller = zygoteServer.runSelectLoop(abiList);
    //执行Runnable的里面的run方法
    if (caller != null) {
        caller.run();
    }
}

在ZygoteServer构造中,回头根据参数isPrimaryZygote去创建主模式socket,还是辅模式socket的服务端:

@frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
ZygoteServer(boolean isPrimaryZygote) {
    mUsapPoolEventFD = Zygote.getUsapPoolEventFD();

    if (isPrimaryZygote) {
        mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
        mUsapPoolSocket =
                Zygote.createManagedSocketFromInitSocket(
                        Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
    } else {
        mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
        mUsapPoolSocket =
                Zygote.createManagedSocketFromInitSocket(
                        Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
    }

    mUsapPoolSupported = true;
    fetchUsapPoolPolicyProps();
}

可以看到,创建主模式的socket用的就是Zygote.PRIMARY_SOCKET_NAME,辅模式用的是Zygote.SECONDARY_SOCKET_NAME。这就与前面连接socket所用的name对应上了。

因为zygote的启动脚本有好几种,采用的是init.zygote32_64这类型的脚本,则name为Zygote.PRIMARY_SOCKET_NAME,如果采用的是zygote_secondary,则name为Zygote.SECONDARY_SOCKET_NAME。

因此AMS是通过socket连接通知zygote需要创建进程,中间根据不同的模式连接不同的socket,将应用启动参数传递进行通信。

Zygote收到请求并创建应用程序进程

在上面socket连接成功并匹配ABI后会返回一个ZygoteState类型对象,然后会将应用进程启动参数写入这个ZygoteState对象中去,这样zygote进程就会通过socket收到创建应用程序进程的请求参数。

那zygote是如何接收参数的呢?在ZygoteInit中创建了ZygoteServer对象后,会进入他的runSelectLoop方法:

@frameworks/base/core/java/com/android/internal/os/ZygoteServer.java#152
/**
 * Runs the zygote process's select loop. Accepts new connections as
 * they happen, and reads commands from connections one spawn-request's
 * worth at a time.
 * @param abiList list of ABIs supported by this zygote.
 */
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) {
        

        if (pollReturnValue == 0) {
            // The poll returned zero results either when the timeout value has been exceeded
            // or when a non-blocking poll is issued and no FDs are ready.  In either case it
            // is time to refill the pool.  This will result in a duplicate assignment when
            // the non-blocking poll returns zero results, but it avoids an additional
            // conditional in the else branch.
            mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP;
            mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED;

        } 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 {
                        //2
                        ZygoteConnection connection = peers.get(pollIndex);
                        boolean multipleForksOK = !isUsapPoolEnabled()
                                && ZygoteHooks.isIndefiniteThreadSuspensionSafe();
                        final Runnable command =
                                connection.processCommand(this, multipleForksOK);

                        ...
                        
                        return command;
                    } 
                    ...

                } else {
                    ...
                }
            }

            ...
        }
        ...
    }
}

当有AMS请求来的时候,会调用注释2的代码,通过调用ZygoteConnection的processCommand方法去处理请求的数据:

@frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
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.
            } catch (IOException ex) {
                throw new IllegalStateException("IOException on command socket", ex);
            }
            ...

            
            if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
                    || !multipleOK || peer.getUid() != Process.SYSTEM_UID) {
                // Continue using old code for now. TODO: Handle these cases in the other path.
                //创建应用程序进程
                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);

                try {
                    if (pid == 0) {
                        //当前代码逻辑在子进程中
                        // in child
                        zygoteServer.setForkChild();

                        zygoteServer.closeServerSocket();
                        IoUtils.closeQuietly(serverPipeFd);
                        serverPipeFd = null;
                        //处理应用程序进程
                        return handleChildProc(parsedArgs, childPipeFd,
                                parsedArgs.mStartChildZygote);
                    } else {
                        // In the parent. A pid < 0 indicates a failure and will be handled in
                        // handleParentProc.
                        IoUtils.closeQuietly(childPipeFd);
                        childPipeFd = null;
                        handleParentProc(pid, serverPipeFd);
                        return null;
                    }
                } finally {
                    IoUtils.closeQuietly(childPipeFd);
                    IoUtils.closeQuietly(serverPipeFd);
                }
            } 
            ...
        }
    }
    ...
}

首先会去获取应用程序进程的启动参数,然后调用Zygote的forkAndSpecialize函数创建应用程序进程。forkAndSpecialize主要是通过fork当前进程来创建一个子进程,如果返回值pid为0,则表示当前代码逻辑在新创建的子进程中,这个时候就回去调用handleChildProc方法去处理应用程序进程:

@frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java#handleChildProc
private Runnable handleChildProc(ZygoteArguments parsedArgs,
        FileDescriptor pipeFd, boolean isZygote) {
    /*
     * By the time we get here, the native code has closed the two actual Zygote
     * socket connections, and substituted /dev/null in their place.  The LocalSocket
     * objects still need to be closed properly.
     */

    closeSocket();

    Zygote.setAppProcessName(parsedArgs, TAG);

    // End of the postFork event.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    if (parsedArgs.mInvokeWith != null) {
        WrapperInit.execApplication(parsedArgs.mInvokeWith,
                parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                VMRuntime.getCurrentInstructionSet(),
                pipeFd, parsedArgs.mRemainingArgs);

        // Should not get here.
        throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
    } else {
        //在子进程中,isZygote为false
        if (!isZygote) {
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(
                    parsedArgs.mRemainingArgs  /* classLoader */);
        }
    }
}

当前进程处于子进程中,因此isZygote必为false,逻辑进入到ZygoteInit的zygoteInit函数中:

@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#zygoteInit
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    ...
    RuntimeInit.commonInit();
    //1.启动Binder线程池
    ZygoteInit.nativeZygoteInit();
    //2.返回Runnable,被调用run方法后进入入口类的main方法
    return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
            classLoader);
}

private static native void nativeZygoteInit();

注释1处会在新创建的应用程序进程中创建Binder线程池,注释2则会调用RuntimeInit的applicationInit方法:

@frameworks/base/core/java/com/android/internal/os/RuntimeInit.java#applicationInit
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    ...
    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

其中args.startClass的值就是上文提到的android.app.ActivityThread,继续到findStaticMain方法:

@frameworks/base/core/java/com/android/internal/os/RuntimeInit.java#findStaticMain
protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class<?> cl;

    try {
        //1.反射获取对象
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

    Method m;
    try {
        //得到main方法
        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);
    }

    /*
     * This throw gets caught in ZygoteInit.main(), which responds
     * by invoking the exception's run() method. This arrangement
     * clears up all the stack frames that were required in setting
     * up the process.
     */
    return new MethodAndArgsCaller(m, argv);
}

通过反射找到android.app.ActivityThread的main方法,然后将参数与方法封装为一个MethodAndArgsCaller类型的Runnable对象返回,供前文去调用run方法,从而执行到ActivityThread的main方法中去。到这里,应用程序进程就创建完成并且运行了主线程的管理类AvtivityThread。

zygote创建的所有进程(应用程序进程和SystemServer进程),都是fork处进程后,在子进程中进入ZygoteInit的静态方法zygoteInit处理进程后续工作:首先创建Binde线程池,目的是为了方便与其他进程进行通信;其次是通过传入的参数,利用反射技术进入到其main函数(应用程序进程的入口是android.app.ActivityThread,SystmeServer的入口是com.android.server.SystemServer