应用程序进程启动过程

1 应用程序进程简介

想要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程已经启动。 AMS 在启动应用程序时会检查这个应用程序所需要的应用程序进程是否已经存在,如果不存在就会请求 Zygote 进程启动需要的应用程序进程。 在 Zygote进程启动过程 中可以知道,在 ZygoteInit.main 方法中会创建一个 Server 端的 Socket 用来等待 AMS 请求 Zygote 进程创建子进程。Zygote 进程通过 fork 自身创建子进程,这样,子进程就会获得 Zygote 进程在启动时创建的 Java 虚拟机实例。

在应用程序的创建过程中,除了获取 Java 虚拟机的实例外,还创建了 Binder 线程池和消息循环,这样运行应用进程中的应用程序就可以使用 Binder 进行进程间通信以及处理消息了。

2 应用程序进程启动过程

应用程序进程创建的过程比较复杂,这里分为两部分, AMS 发送启动应用程序进程请求和 Zygote 接收请求并创建应用程序进程。

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

以下是相关时序图:

应用程序进程启动过程_第1张图片

ActivityManagerServive 如果想要启动应用程序进程,就需要向 Zygote 进程发送创建应用程序进程的请求。AMS 是通过调用 ActivityManagerService.LocalService.startProcess 方法向 Zygote 进程发送请求的,代码如下所示:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final class LocalService extends ActivityManagerInternal {
    @Override
    public void startProcess(String processName, ApplicationInfo info,
                             boolean knownToBeDead, String hostingType, 
                             ComponentName hostingName) {
        try {
            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
                                 + processName);
            }
            synchronized (ActivityManagerService.this) {
                startProcessLocked(processName, info, knownToBeDead, 
                                   0 /* intentFlags */,
                                   new HostingRecord(hostingType, hostingName),
                                   false /* allowWhileBooting */, 
                                   false /* isolated */,
                                   true /* keepIfLarge */); // 1
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }
    
    @GuardedBy("this")
    final ProcessRecord startProcessLocked(String processName,
                                           ApplicationInfo info, 
                                           boolean knownToBeDead, int intentFlags,
                                           HostingRecord hostingRecord, 
                                           boolean allowWhileBooting, 
                                           boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, 
                                               intentFlags,
                                               hostingRecord, allowWhileBooting, 
                                               isolated, 0 /* isolatedUid */, 
                                               keepIfLarge,
                                               null /* ABI override */, 
                                               null /* entryPoint */, 
                                               null /* entryPointArgs */,
                                               null /* crashHandler */); // 2
    }
}

在注释 2 处调用 ProcessList.startProcessLocked 方法,如下所示:

// /frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
                                       boolean knownToBeDead, int intentFlags, 
                                       HostingRecord hostingRecord,
                                       boolean allowWhileBooting, boolean isolated, 
                                       int isolatedUid, boolean keepIfLarge,
                                       String abiOverride, String entryPoint, 
                                       String[] entryPointArgs, Runnable crashHandler) {
    ...
    final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
    ...
}

@GuardedBy("mService")
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
                                 String abiOverride) {
    return startProcessLocked(app, hostingRecord, false /* disableHiddenApiChecks */, 
                              false /* mountExtStorageFull */, abiOverride);
}

@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
                           boolean disableHiddenApiChecks, boolean mountExtStorageFull,
                           String abiOverride) {
    ...
    int uid = app.uid; // 1 获取要创建的应用程序进程的用户 ID
    int[] gids = null;
    int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
    if (!app.isolated) {
		...
        // 2. 对 gids 进行创建和赋值
        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));

    }
    ...
    final String entryPoint = "android.app.ActivityThread"; // 3
    return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, runtimeFlags, 
                              mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                              startTime);
}

@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint,
                           ProcessRecord app, int uid, int[] gids, int runtimeFlags, 
                           int mountExternal, String seInfo, String requiredAbi, 
                           String instructionSet, String invokeWith, long startTime) {
	...
    final Process.ProcessStartResult startResult = startProcess(hostingRecord, entryPoint, app, 
                                                                uid, gids, runtimeFlags, 
                                                                mountExternal, seInfo, 
                                                                requiredAbi, instructionSet,
                                                                invokeWith, startTime);
    ...
}

private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
                                                ProcessRecord app, int uid, int[] gids, 
                                                int runtimeFlags, int mountExternal,
                                                String seInfo, String requiredAbi, 
                                                String instructionSet, String invokeWith,
                                                long startTime) {
	...
    // 4 启动应用程序进程
    startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, 
                                mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, 
                                instructionSet, app.info.dataDir, invokeWith, 
                                app.info.packageName, 
                                new String[] {PROC_START_SEQ_IDENT + app.startSeq});
	...
}

在注释 1 处得到要创建的进程的用户 ID,在注释 2 处对用户组 IDgids) 进行创建和赋值。在注释 3 处将 entryPoint 赋值为 android.app.ActivityThread ,这个值就是应用程序进程主线程的类名。 在注释 4 处调用 Process.start 方法,将此前得到的进程的用户 ID 和用户组 ID 传进去。继续看 Process.start 方法:

// /frameworks/base/core/java/android/os/Process.java
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

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,
                                       @Nullable String[] zygoteArgs) {
    return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                                abi, instructionSet, appDataDir, invokeWith, packageName,
                                /*useUsapPool=*/ true, zygoteArgs); // 1
}

Process.start 方法中调用了 ZygoteProcess.start 方法,其中,ZygoteProcess 类用于保持与 Zygote 进程的通信状态,ZygoteProcess.start 方法如下所示:

// /frameworks/base/core/java/android/os/ZygoteProcess.java
public final Process.ProcessStartResult start(@NonNull final String processClass,
                                              final String niceName,
                                              int uid, int gid, @Nullable int[] gids,
                                              int runtimeFlags, int mountExternal,
                                              int targetSdkVersion,
                                              @Nullable String seInfo,
                                              @NonNull String abi,
                                              @Nullable String instructionSet,
                                              @Nullable String appDataDir,
                                              @Nullable String invokeWith,
                                              @Nullable String packageName,
                                              boolean useUsapPool,
                                              @Nullable String[] zygoteArgs) {
    // TODO (chriswailes): Is there a better place to check this value?
    if (fetchUsapPoolEnabledPropWithMinInterval()) {
        informZygotesOfUsapPoolStatus();
    }

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

在注释 1 处调用了 ZygoteProcess.startViaZygote 方法,代码如下所示:

// /frameworks/base/core/java/android/os/ZygoteProcess.java
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                  @Nullable final String niceName,
                                                  final int uid, final int gid,
                                                  @Nullable final int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  @Nullable String seInfo,
                                                  @NonNull String abi,
                                                  @Nullable String instructionSet,
                                                  @Nullable String appDataDir,
                                                  @Nullable String invokeWith,
                                                  boolean startChildZygote,
                                                  @Nullable String packageName,
                                                  boolean useUsapPool,
                                                  @Nullable String[] extraArgs)
    											throws ZygoteStartFailedEx {
    // 1 创建字符串列表 argsForZygote,并将应用进程的启动参数保存在 argForZygote 中
    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);
	...
    synchronized(mLock) {
        // 2
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), // 3
                                          useUsapPool, argsForZygote); 
    }

}

在注释 1 处创建了字符串列表 argsForZygote,并将启动应用程序进程的启动参数保存在 argsForZygote 中,方法最终会调用 ZygoteProcess.zygoteSendArgsAndGetResult 方法,需要注意的是,ZygoteProcess.zygoteSendArgsAndGetResult 的第一个参数是 ZygoteProcess.openZygoteSocketIfNeeded 方法。ZygoteProcess.zygoteSendArgsAndGetResult 方法如下所示:

// /frameworks/base/core/java/android/os/ZygoteProcess.java
@GuardedBy("mLock")
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
    ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)
    throws ZygoteStartFailedEx {
    for (String arg : args) {
        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 (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {
        try {
            return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
        } catch (IOException ex) {
            Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
                  + ex.getMessage());
        }
    }

    return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr); // 1
}

private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
    ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
    try {
        final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter; // 2
        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);
    }
}

ZygoteProcess.zygoteSendArgsAndGetResult 方法的主要作用就是将传入的引用进程的启动参数 args 写入到 ZygoteState 中。ZygoteStateZygoteProcess 的镜头内部类,用于表示与 Zygote 进程的通信状态,ZygoteState 是由 ZygoteProcess.openZygoteSocketIfNeeded 方法返回的,以下是 ZygoteProcess.openZygoteSocketIfNeeded 方法的代码:

// /frameworks/base/core/java/android/os/ZygoteProcess.java
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    try {
        // 尝试与 Zygote 进程建立连接
        attemptConnectionToPrimaryZygote(); // 1
		// 连接 Zygote 主模式返回的 ZygoteState 是否与启动应用程序进程所需要的 ABI 匹配
        if (primaryZygoteState.matches(abi)) { // 2
            return primaryZygoteState;
        }

        if (mZygoteSecondarySocketAddress != null) {
            // The primary zygote didn't match. Try the secondary. 如果不匹配,则尝试连接 Zygote 辅模式
            attemptConnectionToSecondaryZygote(); // 3

            // 连接 Zygote 辅模式返回的 ZygoteState 是否与启动因公程序进程所需要的 ABI 匹配
            if (secondaryZygoteState.matches(abi)) { // 4
                return secondaryZygoteState;
            }
        }
    } catch (IOException ioe) {
        throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
    }

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

/**
  * 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()) {
        primaryZygoteState =
            ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress); // 5

        maybeSetApiBlacklistExemptions(primaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
        maybeSetHiddenApiAccessStatslogSampleRate(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()) {
        secondaryZygoteState =
            ZygoteState.connect(mZygoteSecondarySocketAddress, mUsapPoolSecondarySocketAddress); // 6

        maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
        maybeSetHiddenApiAccessStatslogSampleRate(secondaryZygoteState);
    }
}  

Zygote 进程启动的过程中,会在 Zygote.main 方法中创建 namezygoteServer 端的 Socket。在注释 5 处会调用 ZygoteState.connect 方法与名称为 PRIMARY_SOCKET_NAMESocket 建立连接并返回 ZygoteState 类型的变量 primaryZygoteState 对象,PRIMARY_SOCKET_NAME 的值为 zygote。在注释 3 处,如果 primaryZygoteState 与启动应用用程序进程所需的 ABI 不匹配,则会在注释 6 处连接 namezygote_secondarySocket。如果这两种模式都不匹配则抛出异常。

Zygote 的启动脚本有 4 种,如果采用的是 init.zygote32_64.rc 或者 init.zygote64_32.rc,则 namezygote 为主模式,namezygote_secondary 为辅模式。

// frameworks/base/core/java/com/android/internal/os/Zygote.java
public static final String PRIMARY_SOCKET_NAME = "zygote";
public static final String SECONDARY_SOCKET_NAME = "zygote_secondary";
public static final String USAP_POOL_PRIMARY_SOCKET_NAME = "usap_pool_primary";
public static final String USAP_POOL_SECONDARY_SOCKET_NAME = "usap_pool_secondary";

// /frameworks/base/core/java/android/os/ZygoteProcess.java
public ZygoteProcess() {
    mZygoteSocketAddress =
        new LocalSocketAddress(Zygote.PRIMARY_SOCKET_NAME, 
                               LocalSocketAddress.Namespace.RESERVED);
    mZygoteSecondarySocketAddress =
        new LocalSocketAddress(Zygote.SECONDARY_SOCKET_NAME,
                               LocalSocketAddress.Namespace.RESERVED);

    mUsapPoolSocketAddress =
        new LocalSocketAddress(Zygote.USAP_POOL_PRIMARY_SOCKET_NAME,
                               LocalSocketAddress.Namespace.RESERVED);
    mUsapPoolSecondarySocketAddress =
        new LocalSocketAddress(Zygote.USAP_POOL_SECONDARY_SOCKET_NAME,
                               LocalSocketAddress.Namespace.RESERVED);
}

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

Zygote 接收到请求并创建应用程序进程的时序图如下所示:

应用程序进程启动过程_第2张图片

Socket 连接成功并匹配 ABI 之后会返回 ZygoteState 类型对象,在 ZygoteProcess.zygoteSendArgsAndGetResult 方法中,会将应用程序进程的启动参数写入到 ZygoteState 中,这样,Zygote 进程就会收到一个创建新的应用程序进程的请求。以下是 ZygoteInit.main 方法的代码:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
    ZygoteServer zygoteServer = null;
    ...
    Runnable caller;
    try {
        if (!enableLazyPreload) {
            bootTimingsTraceLog.traceBegin("ZygotePreload");
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis());
            // 预加载类和资源
            preload(bootTimingsTraceLog); // 1
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis());
            bootTimingsTraceLog.traceEnd(); // ZygotePreload
        } else {
            Zygote.resetNicePriority();
        }
		
        // 创建一个 Server 端的 Socket
        zygoteServer = new ZygoteServer(isPrimaryZygote); // 2
        
        if (startSystemServer) {
            // 启动 system_server 进程
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // 3
            
            if (r != null) {
                r.run();
                return;
            }
        }

        Log.i(TAG, "Accepting command socket connections");
		// 等待 AMS 请求
        caller = zygoteServer.runSelectLoop(abiList); // 4
    }catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }

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

注释 1 处为预加载资源。注释 2 处创建了一个 Server 端的 Socket,这个 namezygoteSocket 用来等待 AMS 来请求 Zygote,以创建新的应用程序进程。注释 3 处为启动 system_server 进程,这样系统服务也就由 system_server 进程启动起来。在注释 4 处调用 ZygoteServer.runSelectLoop 方法来等待 AMS 请求创建新的应用程序进程。以下是 ZygoteServer.runSelectLoop 方法:

// /frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
Runnable runSelectLoop(String abiList) {
    ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
    ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); // 1

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

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

            if (pollIndex == 0) {
                // Zygote server socket
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                socketFDs.add(newPeer.getFileDescriptor());
            } else if (pollIndex < usapPoolEventFDIndex) {
                // Session socket accepted from the Zygote server socket
                try {
                    ZygoteConnection connection = peers.get(pollIndex);
                    final Runnable command = connection.processOneCommand(this); // 2

                    // TODO (chriswailes): Is this extra check necessary?
                    if (mIsForkChild) {
                        if (command == null) {
                            throw new IllegalStateException("command == null");
                        }

                        return command;
                    } else {
                        if (command != null) {
                            throw new IllegalStateException("command != null");
                        }
                        ...
                        if (connection.isClosedByPeer()) {
                            connection.closeSocket();
                            peers.remove(pollIndex);
                            socketFDs.remove(pollIndex);
                        }
                    }
                } catch (Exception e) {
                    ...
                } 
            }
            ...
        }
        ...
    }
}

当有 AMS 的请求数据到来时,会调用注释 2 处的代码,也就是 ZygoteConnection.processOneCommand 方法来处理请求数据的:

// /frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processOneCommand(ZygoteServer zygoteServer) {
    String args[];
    ZygoteArguments parsedArgs = null;
    FileDescriptor[] descriptors;

    try {
        args = Zygote.readArgumentList(mSocketReader); // 1 获取应用程序进程的启动参数

        descriptors = mSocket.getAncillaryFileDescriptors();
    } catch (IOException ex) {
        throw new IllegalStateException("IOException on command socket", ex);
    }

  	...
    int pid = -1;
    ...

    parsedArgs = new ZygoteArguments(args); // 2

    ...
	// 3 创建应用程序进程
    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.mTargetSdkVersion);

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

            zygoteServer.closeServerSocket();
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
			// 处理应用程序进程
            return handleChildProc(parsedArgs, descriptors, 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, descriptors, serverPipeFd);
            return null;
        }
    } finally {
        IoUtils.closeQuietly(childPipeFd);
        IoUtils.closeQuietly(serverPipeFd);
    }
}

在注释 1 处调用 Zygote.readArgumentList 方法来获取应用程序进程的启动参数,并在注释 2 处将返回的字符串数组 args 封装到 ZygoteArguments 类型的 parsedArgs 对象中。在注释 3 处调用 Zygote.forkAndSpecialize 方法来创建应用程序进程,参数为 parsedArgs 中存储的应用进程启动参数,返回值为 pidZygote.forkAndSpecialize 方法主要是通过 fork 当前进程来创建一个子进程的,如果 pid == 0,则说明当前代码的逻辑运行在新创建的子进程(应用程序进程)中,这是就会调用 ZygoteConnection.handleChildProc 方法来处理应用程序进程, 代码如下所示:

// /frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
                                 FileDescriptor pipeFd, boolean isZygote) {
    
    closeSocket();
    ...
    // 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 {
        if (!isZygote) {
            // 1
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                                         parsedArgs.mRemainingArgs, null /* classLoader */); 
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                                              parsedArgs.mRemainingArgs,
                                              null /* classLoader */);
        }
    }
}

ZygoteConnection.handleChildProc 方法中调用了 ZygoteInit.zygoteInit 方法,如下所示:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
                                        ClassLoader classLoader) {
    if (RuntimeInit.DEBUG) {
        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }

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

    RuntimeInit.commonInit();
    ZygoteInit.nativeZygoteInit(); // 1
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); // 2
}

在注释 1 处会在新创建的应用程序进程中创建 Binder 线程池(下面会做详细介绍),在注释 2 处调用了 RuntimeInit.applicationInit 方法:

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
                                          ClassLoader classLoader) {
    ...
    final Arguments args = new Arguments(argv);

    // The end of of the RuntimeInit event (see #zygoteInit).
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader); // 1
}

RuntimeInit.applicationInit 方法会在注释 1 处调用 RuntimeInit.findStaticMain 方法,需要注意的是,第一个参数 arg.startClass,它指的就是 android.app.ActivityThread 接下来查看 RuntimeInit.findStaticMain 方法:

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

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

    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class }); // 2
    } 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);
    }
   	...
    /*
     * 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); // 3
}

在注释 1 处通过反射获得了 android.app.ActivityThread 类,接下来在注释 2 处获得了 ActivityThrea.main 方法,并将 ActivityThread.main 方法传入注释 3 处的 RuntimeInit 中的 MethodAndArgsCaller 类:

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
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 }); // 1
        } 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);
        }
    }
}

注释 1 处的 mMethod 指的是 ActivityThread.main 方法,调用了 mMethod.invoke 方法后,ActivityThread.maim 方法就会被动态调用了,应用程序进程就进入了 ActivityThread.main 方法中。

ZygoteInit.main 方法中调用 MethodAndArgsCaller.run 方法:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
    ...
    Runnable caller;
    ...
    caller = zygoteServer.runSelectLoop(abiList); 
    ... 
    if (caller != null) {
        caller.run();
    }
}

3 Binder 线程池启动过程

ZygoteInit.zygoteInit 方法中会启动 Binder 线程池:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
                                        ClassLoader classLoader) {
    if (RuntimeInit.DEBUG) {
        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }

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

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

private static final native void nativeZygoteInit(); // 2

nativeZygoteInit 方法是一个 JNI 方法,它对应的是 AndroidRuntime.cppJNINativeMethod 数组中的 register_com_android_internal_os_ZygoteInit_nativeZygoteInit,对应的函数是 com_android_internal_os_ZygoteInit_nativeZygoteInit

// /frameworks/base/core/jni/AndroidRuntime.cpp
static const RegJNIRec gRegJNI[] = {
    ...
    REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
    ...
}

int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
         (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
                                    methods, NELEM(methods));
}

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit(); // 1
}

gCurRuntimeAndroidRuntime 类型的指针,它是在 AndroidRuntime 初始化的时候创建的:

// /frameworks/base/core/jni/AndroidRuntime.cpp
static AndroidRuntime* gCurRuntime = NULL;

AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
		mExitWithoutCleanup(false),
		mArgBlockStart(argBlockStart),
		mArgBlockLength(argBlockLength)
{
    SkGraphics::Init();

    // Pre-allocate enough space to hold a fair number of options.
    mOptions.setCapacity(20);

    assert(gCurRuntime == NULL);        // one per process
    gCurRuntime = this;
}

AppRuntiem 继承自 AndroidRuntimeAppRuntime 创建时会调用 AndroidRuntime 的构造函数,gCurRuntime 就会被初始化,它指向的是 AppRuntime。接下来查看 AppRuntime.onZygoteInit 函数,AppRuntimeapp_main.cpp 中实现:

// /frameworks/base/cmds/app_process/app_main.cpp
class AppRuntime : public AndroidRuntime
{
    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();// 1
    }
}

注释 1 处调用了 ProcessState.startThreadPool 函数来启动 Binder 线程池:

// /frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) { // 1
        mThreadPoolStarted = true; // 2
        spawnPooledThread(true);
    }
}

支持 Binder 通信的进程中都有一个 ProcessState 类,它里面有一个 mThreadPoolStarted 变量,用来表示 Binder 线程池是否已经被启动过,默认值是 false,在每次调用 startThreadPool 函数时都会在注释 1 处先检查这个标记,从而确保 Binder 线程池只会启动一次。如果 Binder 线程池未被启动,则在注释 2 处设置 mThreadPoolStarted = true,并调用 spawnPooledThread 函数来创建线程池中的第一个线程,也就是线程池的主线程:

// /frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string()); // 1
    }
}

可以看到 Binder 线程为一个 PoolThread。在注释 1 调用 PoolThread.run 函数来启动一个新的线程,下面是 PoolThread 的相关代码:

// /frameworks/native/libs/binder/ProcessState.cpp
class PoolThread : public Thread
{
    public:
    explicit PoolThread(bool isMain)
        : mIsMain(isMain)
        {
        }

    protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain); // 1
        return false;
    }

    const bool mIsMain;
}; 

PoolThread 继承了 Thread 类,在注释 1 处调用了 IPCThreadStatejoinThreadPool 函数,将当前线程注册到 Binder 驱动中,这样创建的线程就加入了 Binder 线程池中,这样,新创建的应用程序进程就支持 Binder 进程间通信。 我们只需要创建当前进程的 Binder 对象,并将它注册到 ServiceManager 中就可以实现 Binder 进程间通信,而不必关系进程间是如何通过 Binder 进行通信的。

4 消息循环创建过程

通过上面的介绍可以知道,在 ZygoteInit.main 中调用 caller.run ,会执行 MethodAndArgsCaller.run 方法:

// /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
    ...
    Runnable caller;
    ...
    caller = zygoteServer.runSelectLoop(abiList); 
    ... 
    if (caller != null) {
        caller.run();
    }
}

以下是 MethodAndArgsCaller 的相关源码:

// /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
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 }); // 1
        } 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);
        }
    }
}

而注释 1 处的 mMethod 指的是 ActivityThread.main 方法,以下是 ActivityThread.main 的相关源码:

// /frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
    ...
    Looper.prepareMainLooper(); // 1 创建主线程 Looper
    ActivityThread thread = new ActivityThread(); // 2
    thread.attach(false, startSeq);

    if (sMainThreadHandler == null) { // 3
        sMainThreadHandler = thread.getHandler(); // 4 创建主线程的 H 类
    }

    if (false) {
        Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // End of event ActivityThreadMain.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop(); // 5 Looper 开始工作
}

ActivityThread 类用于管理当前应用程序进程的主线程,在注释 1 处创建主线程的消息循环 Looper,在注释 2 处创建 ActivityThread。在注释 3 出判断 Handler 类型的 sMainThreadHandler 是否为 null,如果为 null 则在注释 4 出获取 H 类并赋值给 sMainThreadHandler,这个 H 继承自 Handler,是 ActivityThread 的内部类,用户处理主线程的消息循环。注释 5 处调用 Looper.loop 方法,使得 Looper 开始处理消息。

可以看出,系统在应用程序进程启动完成后,会创建一个消息循环,这样运行在应用程序进程中的应用程序就可以方便的使用消息处理机制。

你可能感兴趣的:(android,java,jvm)