Android5.0源码分析—— Zygote进程分析
1????? Zygote簡介
Android的應用程序一般都是由Java語言編寫而成的,這樣的應用程序需要運行在獨自的Dalvik虛擬機之上(當然,5.0好像默認了ART了)。但是,如果在每一個進程啟動時都在物理內存中創建和初始化一個Dalvik虛擬機,這無疑對系統的性能造成很大的影響。Zygote是Android系統中的一個非常重要的守護進程,所有其他應用程序的Dalvik虛擬機都是通過Zygote孵化出來的。通過這種方式,虛擬機的內存和框架層的資源被所有應用程序共享,從而提高了應用程序的啟動和運行速度。下圖為Android啟動的大致流程。
圖1. Android系統啟動的大致流程
?
2?????Zygote啟動流程分析
2.1???Init進程分析
拋開硬件層的有關內容后,Android的源頭應該為init進程。這個linux進程在操作系統的內核啟動的后期就被啟動了,并且之后所有的進程都是它的子孫進程。Init進程由main()開始,截取的部分代碼如下:
| int main(int argc, char **argv) { ?? ?…… ????//創建并掛載了一些基本的系統文件 ??? mkdir("/dev", 0755); ??? mkdir("/proc", 0755); mkdir("/sys", 0755); ? ??? mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); ??? mkdir("/dev/pts", 0755); ??? mkdir("/dev/socket", 0755); ??? mount("devpts", "/dev/pts", "devpts", 0, NULL); ??? mount("proc", "/proc", "proc", 0, NULL); ??? mount("sysfs", "/sys", "sysfs", 0, NULL); ??? …… ??? //初始化了部分屬性 ??? property_init(); ? ??? …… ??? property_load_boot_defaults(); ? ??? //加載了啟動配置文件,即init.rc文件 ????init_parse_config_file("/init.rc"); ??? //觸發Action ????action_for_each_trigger("early-init", action_add_queue_tail); ? ??? queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); ??? queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); ??? queue_builtin_action(keychord_init_action, "keychord_init"); ??? queue_builtin_action(console_init_action, "console_init"); ??? …… ??? queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); ????queue_builtin_action(property_service_init_action, "property_service_init"); ??? queue_builtin_action(signal_init_action, "signal_init"); ??? …… ??? for(;;) { ??????? int nr, i, timeout = -1; ? ????????execute_one_command();//執行當前Command中的一個命令,Action和Service被啟動 ????????restart_processes();?//重新啟動設置了重新啟動標志位的進程 ????????//監聽來自屬性服務的事件 ??????? if (!property_set_fd_init && get_property_set_fd() > 0) { ??????????? ufds[fd_count].fd = get_property_set_fd(); ??????????? ufds[fd_count].events = POLLIN; ??????????? ufds[fd_count].revents = 0; ??????????? fd_count++; ??????????? property_set_fd_init = 1; ??????? } ????????//監控singal,如果子進程異常退出,內核將拋出SIGCHILD信號,此時將可以對進程進行處理 ??????? //或是回收系統資源,或是重啟子進程 ??????? if (!signal_fd_init && get_signal_fd() > 0) { ???? ???????ufds[fd_count].fd = get_signal_fd(); ??????????? ufds[fd_count].events = POLLIN; ??????????? ufds[fd_count].revents = 0; ??????????? fd_count++; ??????????? signal_fd_init = 1; ??????? } ????????//監聽來自keychord設備的事件,這是個組合按鍵設備 ??????? if (!keychord_fd_init && get_keychord_fd() > 0) { ??????????? ufds[fd_count].fd = get_keychord_fd(); ??????????? ufds[fd_count].events = POLLIN; ??????????? ufds[fd_count].revents = 0; ??????????? fd_count++; ??????????? keychord_fd_init = 1; ??????? } ? ?????? ?…… ????????nr = poll(ufds, fd_count, timeout);//利用poll監聽以上事件 ??????? if (nr <= 0) ??????????? continue; ? ??????? for (i = 0; i < fd_count; i++) { ??????????? if (ufds[i].revents & POLLIN) { ??????????????? if (ufds[i].fd == get_property_set_fd()) ??????????? ????????handle_property_set_fd();//處理屬性服務相關事件 ??????????????? else if (ufds[i].fd == get_keychord_fd()) ??????????????????? handle_keychord();//處理keychord事件 ??????????????? else if (ufds[i].fd == get_signal_fd()) ??????????????????? handle_signal();//處理singal事件 ??????????? } ??????? } ??? } ??? return 0; ? |
Zygote作為一個服務也被定義在了init.rc文件中,由init進程派生出來,配置代碼截取在如下:
| service zygote /system/bin/app_process -Xzygote /system/bin --zygote?--start-system-server ??? class main ????socket zygote stream 660 root system ??? onrestart write /sys/android_power/request_state wake ??? onrestart write /sys/power/state on ??? onrestart restart media ??? onrestart restart netd |
由于Zygote是由java的服務進程,其啟動過程和其他在init.rc文件中定義的service啟動不太一樣。
2.2???App_main.cpp
通過配置信息可以定位Zygote的入口函數為app_main.cpp中的main,其代碼截取如下:
?
| int main(int argc, char* const argv[]) { …… //此類是AndroidRuntime的派生類 ????AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); ??? …… ??? while (i < argc) {//遍歷Zygote的配置參數 ??????? const char* arg = argv[i++]; ??????? if (strcmp(arg, "--zygote") == 0) {//為進程更換名字 ??????????? zygote = true; ??????????? niceName = ZYGOTE_NICE_NAME; ??????? } else if (strcmp(arg, "--start-system-server") == 0) {//設置systemServer為true ??????????? startSystemServer = true; ??????? } else if (strcmp(arg, "--application") == 0) {//設置application啟動為true ??????????? application = true; ??????? } else if (strncmp(arg, "--nice-name=", 12) == 0) { ?????????? …… ??????? } ??? } ??? …… ??? if (zygote) {//如果配置參數中有參數顯示需要啟動Zygote,則ZygoteInit啟動 ????????runtime.start("com.android.internal.os.ZygoteInit", args); ??? } else if (className) {//否則RuntimeInit啟動 ????????runtime.start("com.android.internal.os.RuntimeInit", args); ??? } else { ??????? …… ??? } } |
可見,app_main.cpp中的main()最為主要的是創建了一個AppRuntime變量,接著調用了它的start()成員函數。AppRuntime類繼承自AndroidRuntime類,它并沒有實現自己的start()方法,因此調用的是AndroidRuntime ::start()。而根據之前對App_main.cpp中main函數的分析,傳入到AndroidRuntime.start()的參數存在兩種情況:
1)runtime.start("com.android.internal.os.ZygoteInit",args)
2)runtime.start("com.android.internal.os.RuntimeInit",args)
因此可能存在兩種不同的啟動方式, “RuntimeInit”式啟動時序大致如下圖所示:
圖2.? “RuntimeInit”式啟動時序
由于在init.rc文件的Zygote服務已經配置了相關參數,因此這里只對ZygoteInit進行分析。AndroidRuntime.start()的主要作用是啟動Android系統運行時庫,代碼截取如下:
| void AndroidRuntime::start(const char* className, const Vector<String8>& options) { ??? ……//配置虛擬機的一些參數 ??? JniInvocation jni_invocation; ??? jni_invocation.Init(NULL); JNIEnv* env; //開啟虛擬機 ????if (startVm(&mJavaVM, &env) != 0) { ??????? return; } //這里實際上是調用了子類AppRuntime的onVmCreate(env) onVmCreated(env); //注冊Android JNI函數 ????if (startReg(env) < 0) { ??????? ALOGE("Unable to register all android natives\n"); ??????? return; ??? } ? ????//在開始調用main之前需要將參數轉化成java可識別的類型,并將其全部存入一個數組 ??? jclass stringClass; ??? jobjectArray strArray; ??? jstring classNameStr; ? ??? stringClass = env->FindClass("java/lang/String"); ??? assert(stringClass != NULL); ??? strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); ??? assert(strArray != NULL); ??? classNameStr = env->NewStringUTF(className); ??? assert(classNameStr != NULL); ??? env->SetObjectArrayElement(strArray, 0, classNameStr); ? ??? 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); ??? } char* slashClassName = toSlashClassName(className); //找到需要啟動的java類 ??? jclass startClass = env->FindClass(slashClassName); ??? if (startClass == NULL) { ??????? ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); } else { ??? ????//得到指定類中指定方法的ID,這里得到的是ZygoteInit.main()的方法ID ??????? jmethodID startMeth = env->GetStaticMethodID(startClass, "main", ??????????? "([Ljava/lang/String;)V"); ??????? if (startMeth == NULL) { ??????????? ALOGE("JavaVM unable to find main() in '%s'\n", className); ??????? } else { ????????????//調用上面得到的方法ID和相關參數,即調用Java類ZygoteInit.main(); ????????????env->CallStaticVoidMethod(startClass, startMeth, strArray); ??? ????????…… ??????? } ??? } ??? ……//回收資源關閉虛擬機等操作,這個函數除非進程退出,否則不會返回 } |
AndroidRuntime.start()實際上主要做了3件事:1,startVM開啟虛擬機;2,startReg()注冊了JNI方法;3,調用Java方法。
2.3???ZygoteInit分析
ZygoteInit相關的類圖結構大致如下:
圖3.? ZygoteInit相關類圖結構
根據init.rc中Zygote的配置參數,AndroidRuntime.start()最終調用的是ZgoteInit.main()。其代碼截取如下:
| public static void main(String argv[]) { ??????? try { ??????????? …… ????????????registerZygoteSocket(socketName);//初始化了server(zygote)的一個localsocket ??????????? EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, ???????? ???????SystemClock.uptimeMillis()); ????????????preload();//加載了framwork.jar的class和資源到內存,這部分很占CPU ??????????? EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, ??????????????? SystemClock.uptimeMillis()); ? ??????????? SamplingProfilerIntegration.writeZygoteSnapshot(); ? ????????????gc();//由于后續需要fork出應用程序的進程,需要進行垃圾回收以確保應用程序的性能 ? ??????????? Trace.setTracingEnabled(false); ? ??????????? if (startSystemServer) { ????????????????startSystemServer(abiList, socketName);//開啟System server服務 ??????????? } ? ??????????? Log.i(TAG, "Accepting command socket connections"); ????????????runSelectLoop(abiList);//開啟循環 ? ??????????? closeServerSocket(); ??????? } catch (MethodAndArgsCaller caller) { ????????????caller.run();//這里實際上是真正開啟了systemServer進程 ??????? } catch (RuntimeException ex) { ??????????? Log.e(TAG, "Zygote died with exception", ex); ??????????? closeServerSocket(); ??????????? throw ex; ??????? } ??? } |
在ZygoteInit.main()中首先是調用了registerZygoteSocket(..)方法,該方法主要是為Zygote服務創建了一個localSocket。接著調用preload將class資源和系統的Resource加載到了內存中。之后利用gc()對垃圾進行回收。由于linux的寫時復制機制,在fork出應用程序之前對垃圾進行回收可以最小化子進程的垃圾內存。之后,ZygoteInit.main()分別調用了startSystemServer()、runSelectLoop()方法。startSystemServer()開啟了SystemServer,此進程是Zygote孵化出來的第一個java進程。而runSelectLoop()進入select的循環,用來響應其他應用程序(AMS)的請求。
2.4???Zygote啟動SystemServer服務簡要分析
SystemServer進程是Zygote 孵化出來的第一個進程,此進程有很多的系統進程,提供了所有核心的系統服務。與孵化其他進程不同,Zygote單獨對SystemServer進程做了孵化工作。ZygoteInit.main()中調用了startSystemServer(),代碼如下:
| private static boolean startSystemServer(String abiList, String socketName) ??????????? throws MethodAndArgsCaller, RuntimeException { ??????? long capabilities = posixCapabilitiesAsBits( ??????????? OsConstants.CAP_BLOCK_SUSPEND, ??????????? OsConstants.CAP_KILL, ??????????? OsConstants.CAP_NET_ADMIN, ??????????? OsConstants.CAP_NET_BIND_SERVICE, ??????????? OsConstants.CAP_NET_BROADCAST, ??????????? OsConstants.CAP_NET_RAW, ??????????? OsConstants.CAP_SYS_MODULE, ??????????? OsConstants.CAP_SYS_NICE, ??????????? OsConstants.CAP_SYS_RESOURCE, ??????????? OsConstants.CAP_SYS_TIME, ??????????? OsConstants.CAP_SYS_TTY_CONFIG ??????? ); ????????//SystemServer的啟動參數設置 ??????? String args[] = { ??????????? "--setuid=1000", ??????????? "--setgid=1000", ??????????? "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007", ??????????? "--capabilities=" + capabilities + "," + capabilities, ??????????? "--runtime-init", ??????????? "--nice-name=system_server", ??????????? "com.android.server.SystemServer", ??????? }; ??????? ZygoteConnection.Arguments parsedArgs = null; ? ??????? int pid; ? ??????? try { ??????????? parsedArgs = new ZygoteConnection.Arguments(args); ??????????? ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ??????????? ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); ? ????????????//向Zygote發送fork請求 ????????????pid = Zygote.forkSystemServer( ????????????????????parsedArgs.uid, parsedArgs.gid, ????????????????????parsedArgs.gids, ????????????????????parsedArgs.debugFlags, ????????????????????null, ????????????????????parsedArgs.permittedCapabilities, ????????????????????parsedArgs.effectiveCapabilities); ??????? } catch (IllegalArgumentException ex) { ??????????? throw new RuntimeException(ex); ????? ??} ? ????????//以下代碼僅對子進程SystemServer有效 ??????? if (pid == 0) { ??????????? if (hasSecondZygote(abiList)) { ??????????????? waitForSecondaryZygote(socketName); ??????????? } ????????????handleSystemServerProcess(parsedArgs); ??????? } ??????? return true; ??? } |
進入handleSystemServerProcess(parsedArgs),從代碼中可以看到Zygote根據請求創建了SystemServer進程,這個進程運行handleSystemServerProcess()。此函數對部分參數做了處理,并將剩余的參數傳遞給了SystemServer。
| ??? private static void handleSystemServerProcess( ??????????? ZygoteConnection.Arguments parsedArgs) ??????????? throws ZygoteInit.MethodAndArgsCaller { ? ??????? closeServerSocket(); ??????? //設置默認權限 ????????Os.umask(S_IRWXG | S_IRWXO); ? ??????? if (parsedArgs.niceName != null) { ??????????? Process.setArgV0(parsedArgs.niceName); ??????? } ? ??????? final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); ??????? if (systemServerClasspath != null) { ??????????? performSystemServerDexOpt(systemServerClasspath); ??????? } ? ??????? if (parsedArgs.invokeWith != null) { ??????????? String[] args = parsedArgs.remainingArgs; ??????????? if (systemServerClasspath != null) { ??????????????? String[] amendedArgs = new String[args.length + 2]; ??????????????? amendedArgs[0] = "-cp"; ??????????????? amendedArgs[1] = systemServerClasspath; ??????????????? System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length); ??????????? } ??????????? //一種可能的啟動方式 ??????????? WrapperInit.execApplication(parsedArgs.invokeWith, ??????????????????? parsedArgs.niceName, parsedArgs.targetSdkVersion, ??????????????????? null, args); ??????? } else {//更為常見的啟動方式 ??????????? ClassLoader cl = null; ??????????? if (systemServerClasspath != null) { ??????????????? cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); ??????????????? Thread.currentThread().setContextClassLoader(cl); ??????????? } ??????????? //將余下的參數傳遞給RuntimeInit.zygoteInit處理 ????????????RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); ??????? } ??????? //永遠不會執行到這里 ??? } |
進入RuntimeInit.zygoteInit()
| public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) ??????????? throws ZygoteInit.MethodAndArgsCaller { ??????? if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); ??????? //重定向log ??????? redirectLogStreams(); ???????? //初始化運行環境 ??????? commonInit(); ??????? //啟動binder線程池 ????????nativeZygoteInit(); ??????? //調用應用程序的入口函數 ????????applicationInit(targetSdkVersion, argv, classLoader); ??? } |
進入applicationInit()
| private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller{ ??????? nativeSetExitWithoutCleanup(true); ??????? …… ????????invokeStaticMain(args.startClass, args.startArgs, classLoader); ??? } |
進入invokeStaticMain ()
| private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) ??????????? throws ZygoteInit.MethodAndArgsCaller { ??????? //解析類名 ??????? Class<?> cl; ??????? try { ????????????cl = Class.forName(className, true, classLoader); ??????? } catch (ClassNotFoundException ex) { ??????????? throw new RuntimeException( ??????????????????? "Missing class when invoking static main " + className, ??????????????????? ex); ?????? ?} ??????? //解析main方法 ??????? Method m; ??????? try { ????????????m = cl.getMethod("main", new Class[] { String[].class }); ??????? } catch (NoSuchMethodException ex) { ??????????? throw new RuntimeException( ??????????????????? "Missing static main on " + className, ex); ??????? } catch (SecurityException ex) { ??????????? throw new RuntimeException( ??????????????????? "Problem getting static main on " + className, ex); ??????? } ? ??????? int modifiers = m.getModifiers(); ??????? if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { ??????????? throw new RuntimeException( ??????????????????? "Main method is not public and static on " + className); ??????? } ??????? //這里并沒有直接去調用SystemServer.main()而是拋出了一個異常,這個異常將在//ZygoteInit.main()中被捕捉 ? ??????throw new ZygoteInit.MethodAndArgsCaller(m, argv); ??? } |
這里非常奇怪,invokeStaticMain并沒有像我們想象的那樣直接去調用SystemServer類的有關代碼,它只是獲取了SystemServer.main方法體和有關參數,并將其封裝在一個MethodAndArgsCaller異常中,這個異常將在ZygoteInit.main中被捕捉。具體可以查看之前的代碼。先查看一下這個異常類的設計,進入MethodAndArgsCaller類查看代碼。
| public static class MethodAndArgsCaller extends Exception ??????????? implements Runnable { ????????//調用方法體 ????????private final Method mMethod; ? ????????//調用方法所需要的參數 ????????private final String[] mArgs; ? ??????? public MethodAndArgsCaller(Method method, String[] args) { ??????????? mMethod = method; ??????????? mArgs = args; ??????? } ? ??????? public void run() { ??????????? try { ????????????????//最終還是調用了main()方法 ????????????????mMethod.invoke(null, new Object[] { mArgs }); ??????????? } 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); ??????????? } ??????? } ??? } } |
拋出MethodAndArgsCaller異常分析:MethodAndArgsCaller異常是在startSystemSerer()中拋出的,從單個文件的代碼來看,程序的執行流跳過runSelectLoop(..)。而runSelectLoop()是Zygote的服務的一個非常重要的方法。這顯然不合理??紤]到startSystemServer中開啟了名字為SystemServer的進程(此時,這個子進程程序流還未流入SystemServer.main()),拋出這個異常MethodAndArgsCaller的實際上是handleSystemServerProcess()的,即SystemServer進程,而父進程Zygote并未受影響。因此跳過runSelectLoop(..)是合理的。通過這樣的方式,可以擺脫在啟動初期時設置的堆棧楨。這些應該都和linux的fork機制有關。
以上SystemServer的啟動流程大致時序如下圖所示。
圖4.? SystemServer啟動大致時序
2.5???runSelectLoop()分析
在分析runSelectLoop之前,需要對應用程序的啟動流程作一下簡要的分析。應用程序的主入口是在ActivityThread的main函數,activity的startActivity最終是在ActivityManagerService中執行的。
首先調用的是ActivityManagerService.startProcessLocked()方法,這個方法有多個重載方法,但是都會調用Process.startViaZygote(),這個方法內部實際上是開啟一個localSocket并連接Zygote進程(此時的Zygote正處于runSelectLoop之中監聽事件)。建立連接之后首先是將參數通過localsocket對應的writer對象發送了所要啟動APP的相關參數給Zygote,并等待localsocke對應的inputStream返回一個int型的pid。以及另一個boolean型的參數usingWrapper。
圖5.? 啟動應用程序大致時序
之前已經描述,Zygote在建立ServerSystem服務之后一直處于runSelectLoop循環中,等待AMS的fork請求,runSelectLoop代碼截取如下:
| private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { ??????? ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ??????? ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); ??????? FileDescriptor[] fdArray = new FileDescriptor[4]; ? ??????? fds.add(sServerSocket.getFileDescriptor()); ??????? peers.add(null); ? ??????? int loopCount = GC_LOOP_COUNT; ??????? while (true) { ??????????? int index; ??????????? if (loopCount <= 0) { ??????????????? gc();//在比較空閑的時候執行gc ??????????????? loopCount = GC_LOOP_COUNT; ??????????? } else { ??????????????? loopCount--; ??????????? } ??????????? try { ??????????????? fdArray = fds.toArray(fdArray); ????????????????//這是一個Native方法,其方法內部調用了Select系統函數等待客戶端連接請求 ????????????????index = selectReadable(fdArray);//注意這里的返回值和select()的返回值是不//同的概念,這里Index是活動fd的索引 ??????????? } catch (IOException ex) { ??????????????? throw new RuntimeException("Error in select()", ex); ??????????? } ??????????? if (index < 0) { ??????????????? throw new RuntimeException("Error in select()"); ??????????? } else if (index == 0) {//有連接進入,放入監聽fd隊列 ????????????????ZygoteConnection newPeer = acceptCommandPeer(abiList); ????????????????peers.add(newPeer); ??????????????? fds.add(newPeer.getFileDescriptor()); ??????????? } else {//有請求 ??????????????? boolean done; ????????????????done = peers.get(index).runOnce();//處理請求 ? ??????????????? if (done) { ??????????????????? peers.remove(index); ??????????????????? fds.remove(index); ??????????????? } ??????????? } ??????? } ??? } |
進入runOnce()
| ??? boolean runOnce()?throws ZygoteInit.MethodAndArgsCaller?{ ? ??????? String args[]; ??????? Arguments parsedArgs = null; ??????? FileDescriptor[] descriptors; ? ??????? long startTime = SystemClock.elapsedRealtime(); ? ??????? try { ????????????args = readArgumentList();//讀取傳遞進來的請求參數 ??????????? descriptors = mSocket.getAncillaryFileDescriptors(); ??????? }…… ?????????? ……//fork出應用進程 ????????????pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, ????????????????????parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, ????????????????????parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, ????????????????????parsedArgs.appDataDir); ?????????? …… ??????? try { ?????? ?????if (pid == 0) { ????????????????//?子進程中 ??????????????? IoUtils.closeQuietly(serverPipeFd); ??????????????? serverPipeFd = null; ????????????????handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); ??????????????? return true; ??????????? } else { ????????????????//?父進程中 ??????????????? IoUtils.closeQuietly(childPipeFd); ??????????????? childPipeFd = null; ????????????????//發送pid和usingWrapper給AMS ????????????????return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); ??????????? } ??????? } finally { ??????????? IoUtils.closeQuietly(childPipeFd); ??????????? IoUtils.closeQuietly(serverPipeFd); ??????? } ??? } |
進入handleChildProc()
| ??? private void handleChildProc(Arguments parsedArgs, ??????????? FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) ??????????? throws ZygoteInit.MethodAndArgsCaller { ? ??????? closeSocket(); ??????? ZygoteInit.closeServerSocket(); ???????? …… ??????? if (parsedArgs.niceName != null) {//設置進程名字 ??????????? Process.setArgV0(parsedArgs.niceName); ??????? } ????????//參數中配置了RuntimeInit,這里為true ??????? if (parsedArgs.runtimeInit) { ??????????? if (parsedArgs.invokeWith != null) {//Android中另一種可能的啟動方式 ??????????????? WrapperInit.execApplication(parsedArgs.invokeWith, ??????????????????????? parsedArgs.niceName, parsedArgs.targetSdkVersion, ??????????????????????? pipeFd, parsedArgs.remainingArgs); ??????????? } else {//程序最終會走到這里 ????????????????RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, ????????????????????????parsedArgs.remainingArgs, null); ??????????? } ??????? } else { ?????????? …… ??????? } ??? } |
可看到,handleChildProc最終調用RuntimeInit.ZygoteInit()。這個方法在分析SystemServer啟動過程時已經分析過了,它依次調用了redirectLogStreams()、commonInit()、zygoteInitNative()? applicationInit()并最終調用了invokeStaticMain()拋出異常,在catch塊中運行指定類的main函數。
?
3????????分析與總結
本文主要分析了Android5.0中Zygote的啟動,以及Zygote孵化SystemServer進程和普通應用進程的過程。從以上的分析可以得知,Android充分利用了Linux的一些特性,在保證了內存被盡可能地共享的同時,又保證了系統的性能和速度
原文地址: http://blog.csdn.net/a34140974/article/details/49783781
總結
以上是生活随笔為你收集整理的Android5.0源码分析—— Zygote进程分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android6.0的SMS(短信)源码
- 下一篇: android sina oauth2.