《深入理解Android卷 I》- 第四章 - Zygote - 讀書筆記

1 綜述

Android系統(tǒng)存在兩個(gè)不同的世界:

  • Java世界,主要是Android的SDK,運(yùn)行基于ART/Dalvik虛擬的Java程序
  • Native世界,c/c++開發(fā)的程序

2 Zygote分析

Zygote本身是一個(gè)Native的應(yīng)用程序戳气,和驅(qū)動(dòng)妓笙、內(nèi)核等均無關(guān)系。Zygote是由init進(jìn)程根據(jù)init.rc的配置而創(chuàng)建的催烘。根據(jù)上一章知道init進(jìn)程通過fork/execve執(zhí)行了zygote配置的可執(zhí)行文件/system/bin/app_process,其對(duì)應(yīng)的文件是frameworks/base/cmds/app_process/App_main.cpp

int main(int argc, char* const argv[]){
...//省略
     if (zygote) {
        //由AndroidRuntime來完成start
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else
    ... //省略
}

main函數(shù)比較簡(jiǎn)單搁进,創(chuàng)建 AppRuntime對(duì)象浪感。設(shè)置一些參數(shù),設(shè)置進(jìn)程名稱等饼问,主要操作還在集中在runtime.start(...)函數(shù)中影兽。
AppRuntime繼承了AndroidRuntime重載了onVmCreated(),onStarted(),onZygoteInit(),onExit()四個(gè)函數(shù)。main中調(diào)用的函數(shù)start()AndroidRuntime中實(shí)現(xiàn)

2.1 AppRuntime分析

framework/base/core/jni/AnroidRuntime.cpp

/*
 * Start the Android runtime.  This involves starting the virtual machine
 * and calling the "static void main(String[] args)" method in the class
 * named by "className".
 *
 * Passes the main function two arguments, the class name and the specified
 * options string.
 */
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
//className的值是"com.android.internal.os.ZygoteInit"
...//省略
    //如果環(huán)境變量中沒有ANDROID_ROOT,則新增該變量莱革,并設(shè)置值為“/system"
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
          ...        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }
    /* start the virtual machine */
    //創(chuàng)建虛擬機(jī)
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);
    /* Register android functions.*/
    //注冊(cè)JNI函數(shù)
    if (startReg(env) < 0) {...//錯(cuò)誤峻堰,退出}
    /*
     * We want to call main() with a String array with arguments in it.
     * At present we have two arguments, the class name and an option string.
     * Create an array to hold them.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);//創(chuàng)建String[]
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className); //把nativeString變成JString
    assert(classNameStr != NULL);
    //把className放在數(shù)據(jù)的0位置
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    //把options中的數(shù)據(jù)放入數(shù)組中
    for (size_t i = 0; i < options.size(); ++i) {
        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
        assert(optionsStr != NULL);
        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }
    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
     //把 '.'替換為'/',在native中'.'有特殊含義
    char* slashClassName = toSlashClassName(className); 
   //拿到com.android.internal.os.ZygoteInit的class對(duì)象
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
    ...
    } else {
        //獲取 main函數(shù)的jmeothodID對(duì)象
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
        if (startMeth == NULL) {...}
         else {
         //執(zhí)行main函數(shù)
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
        ...//省略盅视,異常檢測(cè)
        }
    }
    free(slashClassName);
    //Zygote退出捐名,在正常情況下,Zygote不需要退出闹击。
    if (mJavaVM->DetachCurrentThread() != JNI_OK)
        ALOGW("Warning: unable to detach main thread\n");
    if (mJavaVM->DestroyJavaVM() != 0)
        ALOGW("Warning: VM did not shut down cleanly\n");
}

通過分析AndroidRuntime::start(...)可知镶蹋,其中有三個(gè)關(guān)鍵點(diǎn):

  • 創(chuàng)建VM,重點(diǎn)代碼 AndroidRuntime::startVm(...)
  • 注冊(cè)JNI函數(shù)赏半,重點(diǎn)代碼AndroidRuntime::startReg(env)
  • 進(jìn)入Java世界

2.1.1 創(chuàng)建虛擬機(jī)-startVm

framewors/base/core/jni/AnroidRuntime.cpp

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote){
    ....//一大片設(shè)置vm參數(shù)代碼
    /*
     * The default starting and maximum size of the heap.  Larger
     * values should be specified in a product property override.
     */
     //只有看到這個(gè)最親切了 - ^ - 
    parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
    parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
    ...//一大片設(shè)置參數(shù)代碼
     /*
     * Initialize the VM.
     *
     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     * If this call succeeds, the VM is ready, and we can start issuing
     * JNI calls.
     */
     // 調(diào)用JNI_CreateJavaVM創(chuàng)建虛擬機(jī)贺归,pEnv返回當(dāng)前線程的JNIEnv變量
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
    ...    }

    return 0;
}

2.1.2 注冊(cè)JNI函數(shù)-startReg

給虛擬機(jī)注冊(cè)一些JNI函數(shù),因?yàn)镴ava世界中需要調(diào)用一些native方式實(shí)現(xiàn)的函數(shù)断箫。
frameworks/base/core/jni/AnroidRuntime.cpp

int AndroidRuntime::startReg(JNIEnv* env){
    ATRACE_NAME("RegisterAndroidNatives");
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     */
     //設(shè)置Thread類的線程創(chuàng)建函數(shù)為javaCreateThreadEtc (第五章詳解)
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);
    //注冊(cè)jni函數(shù)拂酣,gRegJNI是一個(gè)全局?jǐn)?shù)組。
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
     ...}
    env->PopLocalFrame(NULL);
    return 0;
}

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
    for (size_t i = 0; i < count; i++) {
        //調(diào)用數(shù)組元素的mProc函數(shù)
        if (array[i].mProc(env) < 0) {
        ...    }
    }
    return 0;
}
//保存的是一個(gè)函數(shù)
static const RegJNIRec gRegJNI[] = {
    REG_JNI(register_com_android_internal_os_RuntimeInit),
    REG_JNI(register_android_os_SystemClock),
    ...
    }
//JNI注冊(cè)函數(shù)對(duì)應(yīng)的結(jié)構(gòu)體
#define REG_JNI(name)      { name, #name }
    struct RegJNIRec {
        int (*mProc)(JNIEnv*);
        const char* mName;
    };

register_jni_procs()中調(diào)用每項(xiàng)的mProc(...)函數(shù)瑰枫,實(shí)際實(shí)行的就是每項(xiàng)的的函數(shù)指針踱葛,進(jìn)行對(duì)應(yīng)當(dāng)中的JNI函數(shù)注冊(cè)丹莲,例:
frameworks/base/core/jni/AnroidRuntime.cpp

int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
{
    return jniRegisterNativeMethods(env,
     "com/android/internal/os/RuntimeInit",gMethods, NELEM(gMethods));
}

2.2 進(jìn)入Java世界

vm已經(jīng)創(chuàng)建好了光坝,JNI函數(shù)也注冊(cè)好了,接下來就是執(zhí)行CallStaticVoidMethod(...)調(diào)用執(zhí)行com.android.internal.os.ZygoteInit::main(...)函數(shù)了
frameworks/base/core/java/com/android/internal/os/Zygote.java

public static void main(String argv[]) {
    //創(chuàng)建ZygoteServer甥材,一些Zygote的socket操作已經(jīng)放到了ZygoteServer中
    ZygoteServer zygoteServer = new ZygoteServer();
    /** 沒理解 - start **/
    // Mark zygote start. This ensures that thread creation will throw an error.
        //???通知vm盯另?
        ZygoteHooks.startZygoteNoThreadCreation(); 
  /** 沒理解 - end **/
    // Zygote goes into its own process group.
        try {
            //設(shè)置groupID,好像之前的版本都沒有這個(gè)設(shè)置
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {...}
   }
    try {
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygoteInit");
            RuntimeInit.enableDdms();//開啟DDMS功能
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = 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)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }
        ...//省略
            //為Zygote注冊(cè)sokect
            zygoteServer.registerServerSocket(socketName);
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ZygotePreload");
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload(); //預(yù)加載類和資源
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());
            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PostZygoteInitGC");
            gcAndFinalize();//強(qiáng)制GC一次
            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);

            // Disable tracing so that forked processes do not inherit stale tracing tags from Zygote.
            Trace.setTracingEnabled(false);
            // Zygote process unmounts root storage spaces.
            Zygote.nativeUnmountStorageOnInit();
            ZygoteHooks.stopZygoteNoThreadCreation();
            //啟動(dòng)system_server
            if (startSystemServer) {
                startSystemServer(abiList, socketName, zygoteServer);
            }
        //進(jìn)入循環(huán),等待socket消息
          zygoteServer.runSelectLoop(abiList);
            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run(); //重要
        } catch (RuntimeException ex) {
            zygoteServer.closeServerSocket();
            throw ex;
        }

2.2.1 創(chuàng)建Zygotes socket

Zygote采用socket的方式接收請(qǐng)求洲赵,關(guān)于Zygotesocket操作全部封裝到了ZygoteServer.java
frameworks/base/core/java/com/android/internal/os/Zygote.java

/**
     * Registers a server socket for zygote command connections
     */
    void registerServerSocket(String socketName) {
        if (mServerSocket == null) {
            int fileDesc;
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                String env = System.getenv(fullSocketName);
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) { ..}

            try {
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc); //設(shè)置文件描述符
                //創(chuàng)建Socket的本地服務(wù)端
                mServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {...}
        }
    }

2.2.2 預(yù)加載類和資源

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

 static void preload() {
      ...//Trace
      beginIcuCachePinning();
         ...//Trace
       //預(yù)加載位于framework/base/preload-classes文件中的類
       preloadClasses();
         ...//Trace
      //預(yù)加載資源鸳惯,包含drawable和color等資源
       preloadResources();
          ...//Trace
       //預(yù)加載OpenGL
        preloadOpenGL();
          ...//Trace
        //通過System.loadLibrary()方法商蕴,
        //預(yù)加載"android","compiler_rt","jnigraphics"這3個(gè)共享庫
        preloadSharedLibraries();
        //預(yù)加載文本連接符資源
        preloadTextResources();
        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
        // for memory sharing purposes.
        //僅用于zygote進(jìn)程,用于內(nèi)存共享的進(jìn)程
        WebViewFactory.prepareWebViewInZygote();
        endIcuCachePinning();
        warmUpJcaProviders();
  }

加載class時(shí)采用的Class.forName(...)

//[frameworks/base/core/java/com/android/internal/os/ZygoteInit.java::preloadClasses]
 // Load and explicitly initialize the given class. Use
// Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
// (to derive the caller's class-loader). Use true to force initialization, and
// null for the boot classpath class-loader (could as well cache the
// class-loader of this class in a variable).
Class.forName(line, true, null);

說明:preload_class文件由framework/base/tools/preload工具生成芝发,它需要判斷每個(gè)類加載的時(shí)間是否大于1250微秒绪商,超過這個(gè)時(shí)間的類就會(huì)被寫到preload-classes文件中,最后由zygote預(yù)加載辅鲸。
這個(gè)參數(shù)可以在frameworks/base/tools/preload/WritePreloadedClassFile.java中找到

/**
     * Preload any class that take longer to load than MIN_LOAD_TIME_MICROS us.
     */
    static final int MIN_LOAD_TIME_MICROS = 1250;

2.2.3 總結(jié)

Zygote的分析整體和原書保持一致格郁,按照原書的流程看源碼,基本是一致的独悴。更加面向?qū)ο蟮姆庋b讓源碼看起更加清晰例书。

  • 創(chuàng)建AppRuntime對(duì)象,并調(diào)用它的start刻炒。此后的活動(dòng)則由AppRuntime來控制决采。
  • 調(diào)用startVm創(chuàng)建Java虛擬機(jī),然后調(diào)用startReg來注冊(cè)JNI函數(shù)坟奥。
  • 通過JNI調(diào)用com.android.internal.os.ZygoteInit類的main函數(shù)树瞭,從此進(jìn)入了Java世界。然而在這
    個(gè)世界剛開創(chuàng)的時(shí)候爱谁,什么東西都沒有移迫。
  • 調(diào)用registerZygoteSocket。通過這個(gè)函數(shù)管行,它可以響應(yīng)子孫后代的請(qǐng)求厨埋。同時(shí)Zygote調(diào)用preload(),為Java世界添磚加瓦捐顷。
  • Zygote覺得自己工作壓力太大荡陷,便通過調(diào)用startSystemServer分裂一個(gè)子進(jìn)程system_server來為Java世界服務(wù)。
  • Zygote完成了Java世界的初創(chuàng)工作迅涮,它已經(jīng)很滿足了废赞。下一步該做的就是調(diào)用runSelectLoopMode后,便沉沉地睡去了叮姑。

3 SystemService

Zygote還有一個(gè)重要的作用唉地,啟動(dòng)SystemServer

//啟動(dòng)system_server
if (startSystemServer) {
    startSystemServer(abiList, socketName, zygoteServer);
}

3.1 SystemServer的誕生

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {
        ...//省略
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            //調(diào)用forSystemServerfork一個(gè)新的進(jìn)程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        //systemserver進(jìn)程中
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            zygoteServer.closeServerSocket();
            handleSystemServerProcess(parsedArgs);
        }

        return true;
}

上面代碼調(diào)用了Zygote.forkSystemServer(...)去for新進(jìn)程,進(jìn)入繼續(xù)查看
frameworks/base/core/java/com/android/internal/os/Zygote.java

 public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        VM_HOOKS.preFork();
        //繼續(xù)調(diào)用函數(shù)fork
        int pid = nativeForkSystemServer(
                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
        // Enable tracing as soon as we enter the system_server.
        if (pid == 0) {
            Trace.setTracingEnabled(true);
        }
        VM_HOOKS.postForkCommon();
        return pid;
    }

繼續(xù)調(diào)用一個(gè)native函數(shù)實(shí)現(xiàn)fork,nativeForkSystemServer(...)對(duì)應(yīng)的JNI實(shí)現(xiàn)為com_android_internal_os_Zygote_nativeForkSystemServer(...),文件位置:
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
        jlong effectiveCapabilities) {
        //繼續(xù)調(diào)用函數(shù)fork進(jìn)程
  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
                                      debug_flags, rlimits,
                                      permittedCapabilities, effectiveCapabilities,
                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                      NULL, NULL);
  if (pid > 0) {
      // The zygote process checks whether the child process has died or not.
      // zygote進(jìn)程中传透,檢測(cè)system_server進(jìn)程是否創(chuàng)建
      gSystemServerPid = pid;
      // There is a slight window that the system server process has crashed
      // but it went unnoticed because we haven't published its pid yet. So
      // we recheck here just to make sure that all is well.
      int status;
      if (waitpid(pid, &status, WNOHANG) == pid) {
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
         //當(dāng)system_server進(jìn)程死亡后耘沼,重啟zygote進(jìn)程
          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
      }
  }
  return pid;
}

// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
                                     jint debug_flags, jobjectArray javaRlimits,
                                     jlong permittedCapabilities, jlong effectiveCapabilities,
                                     jint mount_external,
                                     jstring java_se_info, jstring java_se_name,
                                     bool is_system_server, jintArray fdsToClose,
                                     jstring instructionSet, jstring dataDir) {
 //設(shè)置信號(hào)處理
  SetSigChldHandler();
...//省略
    // fork進(jìn)程
  pid_t pid = fork();
  if (pid == 0) {
    //子進(jìn)程
    //關(guān)閉并清除文件描述符
    DetachDescriptors(env, fdsToClose); 
     if (!is_system_server) {
      //對(duì)于非system_server子進(jìn)程,則創(chuàng)建進(jìn)程組
        int rc = createProcessGroup(uid, getpid());
        ...
    }
    //設(shè)置gid
    SetGids(env, javaGids);
    //設(shè)置資源limits
    SetRLimits(env, javaRlimits);
    ...//省略
  }
  ...//省略}

繼續(xù)查看SetSigChldHandler()函數(shù)
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static void SetSigChldHandler() {
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = SigChldHandler;
//設(shè)置處理信號(hào)朱盐。該信號(hào)是子進(jìn)程死亡的信號(hào)
  int err = sigaction(SIGCHLD, &sa, NULL);
...//省略
}

信號(hào)的處理函數(shù)是SigChldHandler(...)
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static void SigChldHandler(int /*signal_number*/) {
  pid_t pid;
  int status;

  // It's necessary to save and restore the errno during this function.
  // Since errno is stored per thread, changing it here modifies the errno
  // on the thread on which this signal handler executes. If a signal occurs
  // between a call and an errno check, it's possible to get the errno set
  // here.
  // See b/23572286 for extra information.
  int saved_errno = errno;

  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
     // Log process-death status that we care about.  In general it is
     // not safe to call LOG(...) from a signal handler because of
     // possible reentrancy.  However, we know a priori that the
     // current implementation of LOG() is safe to call from a SIGCHLD
     // handler in the zygote process.  If the LOG() implementation
     // changes its locking strategy or its use of syscalls within the
     // lazy-init critical section, its use here may become unsafe.
    if (WIFEXITED(status)) {
      if (WEXITSTATUS(status)) {
        ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
      }
    } else if (WIFSIGNALED(status)) {
      if (WTERMSIG(status) != SIGKILL) {
        ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
      }
      if (WCOREDUMP(status)) {
        ALOGI("Process %d dumped core.", pid);
      }
    }

    // If the just-crashed process is the system_server, bring down zygote
    // so that it is restarted by init and system server will be restarted from there.
    //如果死去的子進(jìn)程是SS群嗤,則Zygote把自己也干掉了,Zygote死掉會(huì)導(dǎo)致init重啟zygote,這樣zygote又能啟動(dòng)systemserver
    if (pid == gSystemServerPid) {
    ...
      kill(getpid(), SIGKILL);
    }
  }

  // Note that we shouldn't consider ECHILD an error because
  // the secondary zygote might have no children left to wait for.
  if (pid < 0 && errno != ECHILD) {...}

  errno = saved_errno;
}

由上面代碼可知兵琳,做為Zygote的嫡長(zhǎng)子狂秘,system_server確實(shí)具有非常高的地位骇径,竟然到了與Zygote生死與共的地步!

3.2 SystemServer的重要使命

forksystem_server代碼執(zhí)行回到startSystemServer(...)(frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)中

//[startSystemServer(...)代碼片段]
/* For child process */
if (pid == 0) {
    if (hasSecondZygote(abiList)) {
        //?兩個(gè)zygote進(jìn)程(zygote/zygote64)?之后去了解先寫筆記 
        waitForSecondaryZygote(socketName);
    }
    //關(guān)閉從Zygote那里繼承下來的Socket
    //因?yàn)閒ork()創(chuàng)建新進(jìn)程者春,采用copy on write方式
    //子進(jìn)程繼承了父進(jìn)程的所所有資源破衔?是這么理解吧?
    zygoteServer.closeServerSocket();
    //開啟system_server的使命
    handleSystemServerProcess(parsedArgs);
}

開啟使命:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {
     // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);
    //設(shè)置進(jìn)程名
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }
   final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
       // 執(zhí)行dex優(yōu)化操作
        performSystemServerDexOpt(systemServerClasspath);
    }    
    if (parsedArgs.invokeWith != null) {
        ...    
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = createSystemServerClassLoader(systemServerClasspath,
                                                   parsedArgs.targetSdkVersion);

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

        /*
         * Pass the remaining arguments to SystemServer.
         */
         //調(diào)用ZygoteInit函數(shù)。
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);    
    }
}

其中systemServerClasspath環(huán)境變量主要有/system/framework/目錄下的services.jar钱烟,ethernet-service.jar, wifi-service.jar這3個(gè)文件运敢。
根據(jù)代碼執(zhí)行,繼續(xù)跟入RuntimeInit.zygoteInit(...)函數(shù)
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv,
 ClassLoader classLoader)throws Zygote.MethodAndArgsCaller {
    ...//省略
    //做一些常規(guī)初始化
    commonInit();
    //native層的初始化
    nativeZygoteInit();
    //應(yīng)用初始化
    applicationInit(targetSdkVersion, argv, classLoader); 
 }

zygoteInit(...)主要執(zhí)行了三個(gè)函數(shù)調(diào)用完成忠售。

private static final void commonInit() {
    /*
     * set handlers; these apply to all threads in the VM. Apps can replace
     * the default handler, but not the pre handler.
     */
     // 設(shè)置默認(rèn)的未捕捉異常處理方法
    Thread.setUncaughtExceptionPreHandler(new LoggingHandler());
    Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());

    /*
     * Install a TimezoneGetter subclass for ZoneInfo.db
     */
     // 設(shè)置時(shí)區(qū)传惠,中國(guó)時(shí)區(qū)為"Asia/Shanghai"
    TimezoneGetter.setInstance(new TimezoneGetter() {
        @Override
        public String getId() {
            return SystemProperties.get("persist.sys.timezone");
        }
    });
    TimeZone.setDefault(null);
     //重置log配置
    LogManager.getLogManager().reset();
    new AndroidConfig();

    /*
     * Sets the default HTTP User-Agent used by HttpURLConnection.
     */
     // 設(shè)置默認(rèn)的HTTP User-agent格式,用于 HttpURLConnection
    String userAgent = getDefaultUserAgent();
    System.setProperty("http.agent", userAgent);
     /*
     * Wire socket tagging to traffic stats.
     */
    NetworkManagementSocketTagger.install();
    ...//
}

3.2.1 zygoteInitNative分析

非常重要的函數(shù),單獨(dú)列在一個(gè)小節(jié)里面稻扬。這是一個(gè)native函數(shù)卦方,實(shí)現(xiàn)在frameworks/base/core/jni/AndroidRuntime.cpp

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

gCurRuntimeAndroidRuntime.cpp中的一個(gè)全局靜態(tài)變量

static AndroidRuntime* gCurRuntime = NULL;

app_process.cpp中的main首先就構(gòu)造了一個(gè)AppRuntime對(duì)象

int main(int argc, char* const argv[]){
    ...//省略
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    ...//省略
}

在本章開篇就說了AppRuntime繼承自AndroidRuntime,在構(gòu)造AppRuntime會(huì)先構(gòu)造AndroidRuntime,查看AndroidRuntime的構(gòu)造函數(shù),果然就這這里賦值了:

AndroidRuntime::AndroidRuntime(...):...{
    ...//
    assert(gCurRuntime == NULL); // one per process
    gCurRuntime = this;
}

找到了真身泰佳,繼續(xù)分析onZygoteInit()

 virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ////啟動(dòng)一個(gè)線程盼砍,用于Binder通信。
        proc->startThreadPool();
    }

ProcessState::self()是單例模式逝她,主要工作是調(diào)用open()打開/dev/binder驅(qū)動(dòng)設(shè)備浇坐,再利用mmap()映射內(nèi)核的地址空間,將Binder驅(qū)動(dòng)的fd賦值ProcessState對(duì)象中的變量mDriverFD黔宛,用于交互操作近刘。稍后的章節(jié)中會(huì)詳解

3.2.2 applicationInit(...)

zygoteInit(...)第三個(gè)重要函數(shù):

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
    //true代表應(yīng)用程序退出時(shí)不調(diào)用AppRuntime.onExit(),否則會(huì)在退出前調(diào)用
    nativeSetExitWithoutCleanup(true);
    //設(shè)置虛擬機(jī)的內(nèi)存利用率參數(shù)值為0.75
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
    ...//
     // Remaining arguments are passed to the start class's static main
     //調(diào)用startClass的static方法 main()
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

這里的startClass的參數(shù)就是com.android.server.SystemServer,做了那么多準(zhǔn)備臀晃,終于看到要執(zhí)行main函數(shù)了

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
    Class<?> cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {...}
    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
    ...} catch (SecurityException ex) {
    ...}

    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {...}
    /*
     * 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.
     */
    //拋出一個(gè)異常,清空棧觉渴,提高利用率
    throw new Zygote.MethodAndArgsCaller(m, argv);
}    

由于system_server是從zygote``fork出來的,所以擁有相同的含函數(shù)棧徽惋,只是運(yùn)行在兩個(gè)不同進(jìn)程案淋,互不干擾(不知道這種說法對(duì)不對(duì)...求指教)。所以险绘,這里拋出異常踢京,就會(huì)沿著當(dāng)前的進(jìn)程的函數(shù)棧w往上拋,直到遇到catch宦棺,沿著調(diào)用棧找到
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

//main函數(shù)
try{...} catch (Zygote.MethodAndArgsCaller caller) {
    caller.run();
}

現(xiàn)在函數(shù)執(zhí)行到這里瓣距,對(duì)于zygote進(jìn)程來說,因?yàn)闆]有異常渺氧,繼續(xù)后面的代碼旨涝,而system_server拋出了異常蹬屹,進(jìn)入異常處理代碼:
frameworks/base/core/java/com/android/internal/os/Zygote.java::MethodAndArgsCaller::run()

public void run() {
    try {
        //這個(gè)mMethod為com.android.server.SystemServer的main函數(shù)
        mMethod.invoke(null, new Object[] { mArgs });
    }catch{...}
}

3.2.3 SystemServer的真面目

上面的代碼明確的表示了SystemServermain函數(shù)被調(diào)用
frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {
//創(chuàng)建SystemServer對(duì)象并調(diào)用對(duì)象的run()方法
    new SystemServer().run();
}

private void run() {
    ...//
    //如果時(shí)間當(dāng)前時(shí)間小于1970設(shè)置為1970
    if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
    Slog.w(TAG, "System clock is before 1970; setting to 1970.");
    SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
    }
  ...//
  //變更虛擬機(jī)的庫文件
  SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
  ...//
  //清除vm內(nèi)存增長(zhǎng)上限侣背,由于啟動(dòng)過程需要較多的虛擬機(jī)內(nèi)存空間
  VMRuntime.getRuntime().clearGrowthLimit();
  //設(shè)置內(nèi)存的可能有效使用率為0.8
  VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
  ...//
  //訪問環(huán)境變量前白华,需要明確地指定用戶
  Environment.setUserRequired(true);
  // Within the system server, any incoming Bundles should be defused
  // to avoid throwing BadParcelableException.  
  BaseBundle.setShouldDefuse(true);
  // Ensure binder calls into the system always run at foreground priority.
  //確保當(dāng)前系統(tǒng)進(jìn)程的binder調(diào)用,總是運(yùn)行在前臺(tái)優(yōu)先級(jí)
  BinderInternal.disableBackgroundScheduling(true);
  // Increase the number of binder threads in system_server
  BinderInternal.setMaxThreads(sMaxBinderThreads);
  //進(jìn)程優(yōu)先級(jí)設(shè)置贩耐,和不可自動(dòng)變?yōu)楹笈_(tái)進(jìn)程
  android.os.Process.setThreadPriority(
  android.os.Process.THREAD_PRIORITY_FOREGROUND);
  android.os.Process.setCanSelfBackground(false);
  // Prepare the main looper thread (this thread).
  //準(zhǔn)備當(dāng)前線程的looper
  Looper.prepareMainLooper();
  // Initialize native services.
  //加載android_servers.so
  //該庫的源碼就在frameworks/base/services/core/jni下
  System.loadLibrary("android_servers");
  // Check whether we failed to shut down last time we tried.
  // This call may not return.
  //檢車上次是否關(guān)機(jī)失敗弧腥,這個(gè)方法可能不會(huì)返回
  performPendingShutdown();
  // Initialize the system context.
  //創(chuàng)建system context
  createSystemContext();
  // Create the system service manager.
  //創(chuàng)建SystemServiceManager并添加到本地服務(wù)中
   mSystemServiceManager = new SystemServiceManager(mSystemContext);
   LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
   ...//
   //啟動(dòng)各種服務(wù)
   startBootstrapServices();//引導(dǎo)服務(wù)
   startCoreServices();//核心服務(wù)
   startOtherServices();//其他服務(wù)
   ...//
   //loop
   Looper.loop();
}

SystemServer.run()方法中有很多有趣的函數(shù)調(diào)用可以研究一下

3.2.3.1 performPendingShutdown()

private void performPendingShutdown() {
    //從系統(tǒng)屬性中拿到關(guān)機(jī)的action屬性
    final String shutdownAction = SystemProperties.get(
                ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
    if (shutdownAction != null && shutdownAction.length() > 0) {
        //拿到actiong的第一個(gè)標(biāo)識(shí)為
        boolean reboot = (shutdownAction.charAt(0) == '1');
        //標(biāo)識(shí)位后面都是reason
        final String reason;
        if (shutdownAction.length() > 1) {
            reason = shutdownAction.substring(1, shutdownAction.length());
        } else {
            reason = null;
        }
        ...//檢查確保不是reboot into recovery to apply update
        
        //關(guān)機(jī)或者重啟
        ShutdownThread.rebootOrShutdown(null, reboot, reason);
    }
}

這個(gè)函數(shù)也比較簡(jiǎn)單,獲取系統(tǒng)屬性中是否寫入得有sys.shutdown.requested這個(gè)屬性潮太,如果有就解析這個(gè)屬性管搪,判斷是否要進(jìn)行reboot or shutdwon

3.2.3.2 createSystemContext()

private void createSystemContext() {
    //創(chuàng)建ActivityThread對(duì)象
    ActivityThread activityThread = ActivityThread.systemMain();
    
    mSystemContext = activityThread.getSystemContext();
    //設(shè)置主題
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}

第一個(gè) ActivityThread.systemMain()

public static ActivityThread systemMain() {
        // The system process on low-memory devices do not get to use hardware
        // accelerated drawing, since this can add too much overhead to the
        // process.
    //內(nèi)存低的設(shè)備關(guān)閉硬件加速铡买,因?yàn)闀?huì)增加很多開銷
    if (!ActivityManager.isHighEndGfx()) {
        ThreadedRenderer.disable(true);
    } else {
        ThreadedRenderer.enableForegroundTrimming();
    }
    //創(chuàng)建AcvityThread
    ActivityThread thread = new ActivityThread();
    //創(chuàng)建Application以及調(diào)用其onCreate()方法
    thread.attach(true);
    return thread;
}

3.2.4開啟其他的服務(wù)

SystemServer.run()方法的里更鲁,也是SystemServer最重要的任務(wù),啟動(dòng)系統(tǒng)服務(wù):startBootstrapServices()奇钞,startCoreServices()澡为,startOtherServices()`

3.2.4.1 startBootstrapServices

private void startBootstrapServices() {
    //確保installer服務(wù)先啟動(dòng),在installer內(nèi)部有LocalSocket,先mark景埃,以后在分析
    Installer installer = mSystemServiceManager.startService(Installer.class);
    // Activity manager runs the show.
    mActivityManagerService = mSystemServiceManager.startService(
        ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    // Power manager needs to be started early because other services need it.
    // Native daemons may be watching for it to be registered so it must be ready
    // to handle incoming binder calls immediately (including being able to verify
    // the permissions for those calls).
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
    // Now that the power manager has been started, let the activity manager
    // initialize power management features
    //初始化activityManagerService的power management功能
    mActivityManagerService.initPowerManagement();
    //啟動(dòng)服務(wù)LightsService
    mSystemServiceManager.startService(LightsService.class);
    // Display manager is needed to provide display metrics before package manager
    // starts up.
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
    // We need the default display before we can initialize the package manager.
    //方法里面追個(gè)調(diào)用已經(jīng)添加到serviceManager中service,通知它們當(dāng)前階段??媒至??先留著,因?yàn)檫€有很多phase
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY)
    // Only run "core" apps if we're encrypting the device.
    //獲得系統(tǒng)屬性谷徙,設(shè)備加密的狀態(tài)拒啰,如果在加密只運(yùn)行核心服務(wù)
    String cryptState = SystemProperties.get("vold.decrypt");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        mOnlyCore = true;
    }
    //啟動(dòng)服務(wù)PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();
    ...//不知道在說什么,注釋也不會(huì)翻譯
    // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
    // A/B artifacts after boot, before anything else might touch/need them.
    // Note: this isn't needed during decryption (we don't have /data anyways).
    if (!mOnlyCore) {...}
    //啟動(dòng)服務(wù)UserManagerService
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
    // Initialize attribute cache used to cache resources from packages.
    AttributeCache.init(mSystemContext);
    // Set up the Application instance for the system process and get started.
    mActivityManagerService.setSystemProcess();
    // The sensor service needs access to package manager service, app ops
    // service, and permissions service, therefore we start it after them.
    //傳感器服務(wù)需要訪問其他服務(wù)才能才能完慧,所以最后開啟
    startSensorService();
}

來總結(jié)一下上面創(chuàng)建了哪些serviceInstaller,ActivityManagerService,PowerManagerService,LightsService,DisplayManagerService,PackageManagerService,UserManagerService,SensorService谋旦。啟動(dòng)順序也是有講究的。

3.2.4.2 startCoreServices

private void startCoreServices() {
    // Tracks the battery level.  Requires LightService.
    //啟動(dòng)服務(wù)BatteryService屈尼,用于統(tǒng)計(jì)電池電量
    mSystemServiceManager.startService(BatteryService.class);

    // Tracks application usage stats.
    //追蹤應(yīng)用使用狀態(tài)
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));

    // Tracks whether the updatable WebView is in a ready state and watches for update installs.
    //啟動(dòng)服務(wù)WebViewUpdateService
    mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}

三個(gè)服務(wù):BatteryService,UsageStatsService,WebViewUpdateService.

3.2.4.3 startOtherServices()

啟動(dòng)其他的服務(wù)蛤织,非常多。

private void startOtherServices() {
//太多了鸿染,還是不寫了
...
}

3.3 總結(jié)

System_server真是是非常重要指蚜,他需要負(fù)責(zé)將啟動(dòng)service,特別是它他拋出異常涨椒,然后通過catch異常來執(zhí)行SystemServer的main函數(shù)摊鸡,不知道我理解的對(duì)不對(duì)。

4 Zygote的分裂

Zygote forksystem_server后執(zhí)行zygoteServer.runSelectLoop(...)等待處理請(qǐng)求.

4.1 ActivityManagerService發(fā)送請(qǐng)求

ActivityManagerService是由system_server啟動(dòng)的蚕冬,并且是在startBootStrapServices中啟動(dòng)的免猾,書中直接就給出了在ActivityManagerService:: startProcessLocked(...)來發(fā)起請(qǐng)求。第一次看到肯定還是很懵的囤热。熟悉了app啟動(dòng)流程就知道猎提,創(chuàng)建一個(gè)新的app進(jìn)程,層層調(diào)用旁蔼,最終就會(huì)執(zhí)行到這個(gè)函數(shù)锨苏。
參考:
Android應(yīng)用程序啟動(dòng)過程源代碼分析
frameworks/base/services/java/com/android/server/SystemServer.java

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    ...//僅梳理流程疙教,具體代碼不詳細(xì)解析,因?yàn)槲叶歼€沒弄懂...哈哈伞租。
    //請(qǐng)求創(chuàng)建進(jìn)程
    Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
    ...//省略
}

這里面的代碼很多贞谓,這部分我覺得作者只是回應(yīng)Zygotesocket的作用,重點(diǎn)不在分析ActivityManagerService所以不去深究其它的葵诈,因?yàn)樘珡V了裸弦。
上面的start(...)最終會(huì)執(zhí)行到:
frameworks/base/core/java/com/android/os/ZygoteProcess.java

 private Process.ProcessStartResult startViaZygote(...)
throws ZygoteStartFailedEx {
    ...//省略
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}

openZygoteSocketIfNeeded(...)就是打開socket連接,zygoteSendArgsAndGetResult(...)發(fā)送請(qǐng)求作喘,并讀取結(jié)果理疙。

4.2 Zygote的響應(yīng)

上面已經(jīng)給Zygote發(fā)送的請(qǐng)求,處理的函數(shù)就是zygoteServer.runSelectLoop(...)
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
    ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
    ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();

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

    while (true) {
        //不端的查詢
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        for (int i = 0; i < pollFds.length; ++i) {
            pollFds[i] = new StructPollfd();
            pollFds[i].fd = fds.get(i);
            pollFds[i].events = (short) POLLIN;
        }
        try {
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
            throw new RuntimeException("poll failed", ex);
        }
        for (int i = pollFds.length - 1; i >= 0; --i) {
            //沒有客戶端連接
            if ((pollFds[i].revents & POLLIN) == 0) {
                continue;
            }
            if (i == 0) {
                //獲得新的連接
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                //處理請(qǐng)求
                boolean done = peers.get(i).runOnce(this);
                if (done) {
                    peers.remove(i);
                    fds.remove(i);
                }
            }
        }
    }
}

那么可以看到泞坦,有請(qǐng)求來就會(huì)去執(zhí)行runOnce(...)這個(gè)函數(shù):
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

boolean runOnce(ZygoteServer zygoteServer) 
throws Zygote.MethodAndArgsCaller {
    ...//
    //讀取寫入的參數(shù)
    args = readArgumentList();
    ...//
    //for進(jìn)程
    pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, 
                    parsedArgs.gids, parsedArgs.debugFlags, 
                    rlimits, parsedArgs.mountExternal, 
                    parsedArgs.seInfo,
                    parsedArgs.niceName, 
                    fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);    
    if (pid == 0) {
    // in child
        zygoteServer.closeServerSocket();
        IoUtils.closeQuietly(serverPipeFd);
        serverPipeFd = null;
        //處理子進(jìn)程
        handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

        // should never get here, the child is expected to either
        // throw Zygote.MethodAndArgsCaller or exec().
        return true;
    } else {
        // in parent...pid of < 0 means failure
        IoUtils.closeQuietly(childPipeFd);
        childPipeFd = null;
        return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
    }
    ...//
}
//處理函數(shù)
private void handleChildProc(Arguments parsedArgs,
            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
            throws Zygote.MethodAndArgsCaller {
    ...//省略
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }
    // End of the postFork event.
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    if (parsedArgs.invokeWith != null) {
        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(),
                pipeFd, parsedArgs.remainingArgs);
    } else {
        //進(jìn)入這個(gè)分支
        //很熟悉沪斟,貌似見過。
        //對(duì)暇矫,是他是他就是他主之,在system_server啟動(dòng)的時(shí)候也是掉了這個(gè),最后還拋了異忱罡回到main函數(shù)
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                parsedArgs.remainingArgs, null /* classLoader */);
    }
}

5 總結(jié)

Zygote在Java世界是爸爸槽奕,其他的都是他fork出來的,包括非常重要system_server,其次zygote還要這響應(yīng)創(chuàng)建應(yīng)用的請(qǐng)求房轿。system_server也是不得了粤攒,是老大。Java世界的服務(wù)都得由他來啟動(dòng)囱持。

上一篇 《第三章 - Init》讀書筆記
下一篇 《第五章 - 常見類》讀書筆記

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夯接,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子纷妆,更是在濱河造成了極大的恐慌盔几,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掩幢,死亡現(xiàn)場(chǎng)離奇詭異逊拍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)际邻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門芯丧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人世曾,你說我怎么就攤上這事缨恒。” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵骗露,是天一觀的道長(zhǎng)岭佳。 經(jīng)常有香客問我,道長(zhǎng)椒袍,這世上最難降的妖魔是什么驼唱? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任藻茂,我火速辦了婚禮驹暑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辨赐。我一直安慰自己优俘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布掀序。 她就那樣靜靜地躺著帆焕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪不恭。 梳的紋絲不亂的頭發(fā)上叶雹,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音换吧,去河邊找鬼折晦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛沾瓦,可吹牛的內(nèi)容都是我干的满着。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼贯莺,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼风喇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缕探,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤魂莫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后爹耗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豁鲤,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年鲸沮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了琳骡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讼溺,死狀恐怖楣号,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤炫狱,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布藻懒,位于F島的核電站,受9級(jí)特大地震影響视译,放射性物質(zhì)發(fā)生泄漏嬉荆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一酷含、第九天 我趴在偏房一處隱蔽的房頂上張望鄙早。 院中可真熱鬧,春花似錦椅亚、人聲如沸限番。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弥虐。三九已至,卻和暖如春媚赖,著一層夾襖步出監(jiān)牢的瞬間霜瘪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工惧磺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颖对,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓豺妓,卻偏偏與公主長(zhǎng)得像惜互,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子琳拭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容