天天看點

Android 11 程序啟動分析(一): Zygote程序

一、init程序

Android 10之後的版本,init程序入口源碼在system/core/init/main.cpp,而不在init.cpp。其main函數如下:

int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
    __asan_set_error_report_callback(AsanReportCallback);
#endif

    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }

    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();

            return SubcontextMain(argc, argv, &function_map);
        }

        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }

        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }

    return FirstStageMain(argc, argv);
}
           

這裡不深入init程序隻關注zygote程序的建立,啟動腳本init.rc中有這麼一句:

import /system/etc/init/hw/init.${ro.zygote}.rc
           

對應腳本檔案為init.zygote32.rc或init.zygote64.rc,内容如下:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks
           

二、zygote程序

zygote程序啟動後,會執行到frameworks/base/cmds/app_process/app_main.cpp的main函數

int main(int argc, char* const argv[])
{
    ...

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    
    ... //省略若幹行

    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }

    ... //省略若幹行

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}
           

主要是解析各種啟動參數,然後啟動AppRuntime,顯然這裡zygote是true,執行的是

AppRuntime是AndroiRuntime的派生類,start函數定義在AndroiRuntime類下

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ... //省略若幹行

    /* 啟動虛拟機 */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     * 注冊Android JNI
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    ... //省略若幹行

    //找到并執行Java類的main方法
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
            ... //省略若幹行
        }

    ... //省略若幹行
}
           

這就進入了Java的世界了。由上可知,Java世界的入口是com.android.internal.os.ZygoteInit的main方法

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

    ... // 省略若幹行

    Runnable caller;
    try {
        
        ... // 省略若幹行

        // 解析參數
        boolean startSystemServer = false;
        String zygoteSocketName = "zygote";
        String abiList = null;
        boolean enableLazyPreload = false;
        for (int i = 1; i < argv.length; i++) {
            if ("start-system-server".equals(argv[i])) {
                startSystemServer = true;
            } else if ("--enable-lazy-preload".equals(argv[i])) {
                enableLazyPreload = true;
            } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                abiList = argv[i].substring(ABI_LIST_ARG.length());
            } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
            } else {
                throw new RuntimeException("Unknown command line argument: " + argv[i]);
            }
        }

        ... // 省略若幹行

        if (startSystemServer) {
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
            // child (system_server) process.
            if (r != null) {
                r.run();
                return;
            }
        }

        Log.i(TAG, "Accepting command socket connections");

        // The select loop returns early in the child process after a fork and
        // loops forever in the zygote.
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        if (zygoteServer != null) {
            zygoteServer.closeServerSocket();
        }
    }

    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.
    if (caller != null) {
        caller.run();
    }
}
           

在這裡我們主要關心兩件事情:

  1. SystemServer的啟動
  2. 其他子程序的啟動

三、關于fork程序

這裡插播一下關于fork程序相關知識。fork函數定義在“unistd.h”裡,作用是克隆一個一摸一樣的程序。看如下示例:

#include <iostream>
#include <unistd.h>

using namespace std;

int main() {
    cout << "fork程序測試" << endl;

    int var = 10;

    // fork程序
    int pid = fork();
    if(pid == -1) {
        cout << "fork程序失敗" << endl;
        return -1;
    }

    cout << "我的子程序id:" << pid << endl;

    if (pid) {
        cout << "我的程序id是:" << getpid() << ",變量var是: " << var << endl;
        return 0;
    } else {
        cout << "我的程序id是:" << getpid() << ",變量var是: " << var << endl;
        return 0;
    }
} 
           

輸出結果:

fork程序測試
我的子程序id:13875
我的程序id是:13874,變量var是: 10
我的子程序id:0
我的程序id是:13875,變量var是: 10
           

在fork傳回的時候已經是兩個程序了,父程序中得到的pid是子程序的id,而子程序得到的pid則是0。父程序和子程序就此分道揚镳,沿着不同的分支繼續運作。在父程序中pid非0,是以執行的是if分支,而子程序相反,執行的是else分支。

四、SystemServer的啟動

SystemServer的啟動為:

if (startSystemServer) {
    Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

    // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
    // child (system_server) process.
    if (r != null) {
        r.run();
        return;
    }
}
           

這裡fork了一個子程序,父程序中傳回的Runnable為null,會繼續往下運作;而子程序也就是SystemServer的程序則會調用傳回的Ruunable的run方法,進入SystemServer的邏輯。

這裡我們跟進forkSystemServer方法:

/**
 * Prepare the arguments and forks for the system server process.
 *
 * @return A {@code Runnable} that provides an entrypoint into system_server code in the child
 * process; {@code null} in the parent.
 */
private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {

    ... // 省略若幹行

    String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                    + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs = null;

    int pid;

    try {
        parsedArgs = new ZygoteArguments(args);

        ... // 省略若幹行

        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    if (pid == 0) { // 子程序
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        zygoteServer.closeServerSocket();
        return handleSystemServerProcess(parsedArgs);
    }

    return null;
}
           

可以看到,父程序中确實傳回了null,而子程序傳回值由handleSystemServerProcess确定,我們繼續跟進:

/**
 * Finish remaining work for the newly forked system server process.
 */
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {

    ... // 省略若幹行

    // 上面forkSystemServer方法中定義的啟動參數顯然沒有“--invoke-with”,是以這裡執行的是else分支
    if (parsedArgs.mInvokeWith != null) {

        ... // 省略若幹行

    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);

            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
            * Pass the remaining arguments to SystemServer.
            */
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                parsedArgs.mDisabledCompatChanges,
                parsedArgs.mRemainingArgs, cl);
    }

    /* should never reach here */
}
           

繼續跟進ZygoteInit.zygoteInit方法

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

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

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

這裡進行了一些初始化,然後又轉到了RuntimeInit.applicationInit方法,繼續跟進

protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
    // If the application calls System.exit(), terminate the process
    // immediately without running any shutdown hooks.  It is not possible to
    // shutdown an Android application gracefully.  Among other things, the
    // Android runtime shutdown hooks close the Binder driver, which can cause
    // leftover running threads to crash before the process actually exits.
    nativeSetExitWithoutCleanup(true);

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

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

這裡進行了一通的設定之後,轉到findStaticMain方法,繼續跟進

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

    cl = Class.forName(className, true, classLoader);
    

    Method m;
    m = cl.getMethod("main", new Class[] { String[].class });


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

    return new MethodAndArgsCaller(m, argv);
}
           

這裡通過反射找到目标類的靜态main方法,然後包裝成了MethodAndArgsCaller對象傳回。MethodAndArgsCaller實作了Runnable接口,run方法非常簡單,就是反射執行了目标類的靜态main方法。而這裡說的目标類顯然是forkSystemServer定義的args參數最後一行的“com.android.server.SystemServer”

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

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

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

    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (...) {
            ...
        }
    }
}
           

再回過頭看ZygoteInit的main方法

if (startSystemServer) {
    Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
    if (r != null) {
        r.run();
        return;
    }
}
           

至此SystemServer就正式啟動了。

五、其他程序的啟動

再看ZygoteInit的main方法

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

    ... // 省略若幹行

    Runnable caller;
    try {
        
        ... // 省略若幹行
        zygoteServer = new ZygoteServer(isPrimaryZygote);
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (...) {
        ...
    }

    // We're in the child process and have exited the select loop. Proceed to execute the
    // command.
    if (caller != null) {
        caller.run();
    }
}
           

SystemServer程序啟動後,父程序繼續往下運作到ZygoteServer的runSelectLoop方法。一般我們看到loop就知道這是一個循環,當需要建立新的程序的消息到來的時候,子程序會退出循環往下執行,而父程序則繼續循環。

其中ZygoteServer的構造方法裡啟動了socket監聽

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

這裡分享一個小技巧,根據上面的分析,我們知道傳回一個非null的Runnable對象則會進入一個新的程序,是以我們在分析runSelectLoop方法的時候隻關注傳回的地方,其他的我們暫時不過多關注。

跟進runSelectLoop方法

Runnable runSelectLoop(String abiList) {
    
    ... // 省略若幹行

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

    ... // 省略若幹行

    ZygoteConnection connection = peers.get(pollIndex);
    final Runnable command = connection.processOneCommand(this);

    if (mIsForkChild) {

        ... // 省略若幹行

        return command;
    }

    ... // 省略若幹行

    if (mUsapPoolRefillAction != UsapPoolRefillAction.NONE) {

        ... // 省略若幹行

        final Runnable command =
                fillUsapPool(sessionSocketRawFDs, isPriorityRefill);

        if (command != null) {
            return command;
        } 

        ... // 省略若幹行
    }

    ... // 省略若幹行

}
           

可以看到有兩個地方會傳回Runnable,分别是ZygoteConnection#processOneCommand方法和ZygoteServer#fillUsapPool方法。

5.1 processOneCommand

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

    ... // 省略若幹行

    args = Zygote.readArgumentList(mSocketReader);
    
    ... // 省略若幹行

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

    ... // 省略若幹行

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

    ... // 省略若幹行
    
}
           

可以看到,在通過socker接收一系列參數之後,fork了一個子程序,然後轉到了handleChildProc,繼續跟進

private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
    
    ... // 省略若幹行

    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) {
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mRemainingArgs, null /* classLoader */);
        }
    }
}
           

這裡有3個分支,WrapperInit#execApplication,ZygoteInit#zygoteInit和ZygoteInit#childZygoteInit

5.1.1 WrapperInit#execApplication

/**
 * Executes a runtime application with a wrapper command.
 * This method never returns.
 */
public static void execApplication(String invokeWith, String niceName,
        int targetSdkVersion, String instructionSet, FileDescriptor pipeFd,
        String[] args) {
    StringBuilder command = new StringBuilder(invokeWith);

    ... // 省略若幹行

    Zygote.execShell(command.toString());
}
           

這裡看起來是執行shell指令,根據注釋描述,這個方法永遠不會傳回

5.1.2 ZygoteInit#zygoteInit

public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
    
    ... // 省略若幹行

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

到了RuntimeInit#applicationInit,就和SystemServer程序分析後半段一樣了。

5.1.3 ZygoteInit#childZygoteInit

static final Runnable childZygoteInit(
            int targetSdkVersion, String[] argv, ClassLoader classLoader) {
        RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv);
        return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
    }
           

一目了然。

5.2 fillUsapPool

/**
 * Refill the USAP Pool to the appropriate level, determined by whether this is a priority
 * refill event or not.
 */

Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) {
    
    ... // 省略若幹行

    while (--numUsapsToSpawn >= 0) {
        Runnable caller =
                Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs, isPriorityRefill);

        if (caller != null) {
            return caller;
        }
    }

    ... // 省略若幹行

    return null;
}
           

一般我們看到pool,就會想到這是緩存、複用或者預加載優化相關,比如ThreadPool、RecycledViewPool等等。這裡進行了一個循環,一直fork直至這個Usap程序池填滿。

跟進forkUsap

/**
 * Fork a new unspecialized app process from the zygote
 *
 * @param usapPoolSocket  The server socket the USAP will call accept on
 * @param sessionSocketRawFDs  Anonymous session sockets that are currently open
 * @param isPriorityFork  Value controlling the process priority level until accept is called
 * @return In the Zygote process this function will always return null; in unspecialized app
 *         processes this function will return a Runnable object representing the new
 *         application that is passed up from usapMain.
 */
static Runnable forkUsap(LocalServerSocket usapPoolSocket,
                            int[] sessionSocketRawFDs,
                            boolean isPriorityFork) {
    ... // 省略若幹行

    int pid =
            nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(),
                            sessionSocketRawFDs, isPriorityFork);

    if (pid == 0) {
        IoUtils.closeQuietly(pipeFDs[0]);
        return usapMain(usapPoolSocket, pipeFDs[1]);
    } 
    
    ... // 省略若幹行
}
           

跟進usapMain

/**
 * This function is used by unspecialized app processes to wait for specialization requests from
 * the system server.
 *
 * @param writePipe  The write end of the reporting pipe used to communicate with the poll loop
 *                   of the ZygoteServer.
 * @return A runnable oject representing the new application.
 */
private static Runnable usapMain(LocalServerSocket usapPoolSocket,
                                    FileDescriptor writePipe) {
    

    LocalSocket sessionSocket = null;
    DataOutputStream usapOutputStream = null;
    Credentials peerCredentials = null;
    ZygoteArguments args = null;


    while (true) {
        try {
            sessionSocket = usapPoolSocket.accept();

            BufferedReader usapReader =
                    new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
            usapOutputStream =
                    new DataOutputStream(sessionSocket.getOutputStream());

            peerCredentials = sessionSocket.getPeerCredentials();

            String[] argStrings = readArgumentList(usapReader);

            args = new ZygoteArguments(argStrings);
        } catch (...) {
            ...
        }

        ...

        specializeAppProcess(args.mUid, args.mGid, args.mGids,
                                args.mRuntimeFlags, rlimits, args.mMountExternal,
                                args.mSeInfo, args.mNiceName, args.mStartChildZygote,
                                args.mInstructionSet, args.mAppDataDir, args.mIsTopApp,
                                args.mPkgDataInfoList, args.mWhitelistedDataInfoList,
                                args.mBindMountAppDataDirs, args.mBindMountAppStorageDirs);



        return ZygoteInit.zygoteInit(args.mTargetSdkVersion,
                                            args.mDisabledCompatChanges,
                                            args.mRemainingArgs,
                                            null /* classLoader */);
        }
}

           

根據注釋,Usap為“unspecialized app processes”的縮寫,應該可以了解為未指定App的程序,運作到這裡會循環阻塞,直到通過socket接收到App相關參數,然後使用這個程序啟動App。是以這裡推測UsapPool程序池為預先建立一定數量的程序,然後等待需要啟動App的指令到達,然後使用預先fork的程序啟動App而不是每次都走fork流程,加快App啟動。

ZygoteInit#zygoteInit上面已經分析過,這裡就不再贅述了。

六、總結

  1. init程序為使用者空間(相對于核心空間)的第一個程序,根據init.rc啟動Zygote程序。
  2. Zygote程序啟動步驟:建立虛拟機、注冊JNI、執行ZygoteInit的main方法開始Java之旅。
  3. Zygote程序啟動了SystemServer程序。
  4. Zygote建立了socket,得到建立程序的指令到來,通過fork建立使用者程序。
  5. Zygote有一個優化程序建立的機制,UsapPool。

後續将繼續探讨SystemServer内部運作機制以及App程序建立流程。本文完。