目錄java
一、Zygote簡介android
二、Zygote進程如何啓動ios
2.1 init.zygote64_32.rc文件服務器
2.2 查看ps信息app
2.3 啓動框架
三、Zygote做用socket
3.1 啓動system_server函數
3.2 查看與驗證Zygote啓動systemserveroop
3.3 Zygote啓動其餘子進程post
四、總結
一、Zygote簡介
- 1.1 系統啓動流程
-
從按下電源到看到launcher,手機的啓動是一個很是複雜的過程。
bootloader是手機上電以後第一個運行的程序,其做用是硬件的初始化,其做用相似於PC機的bios。
bootloader完成其工做後,將 Linux kernel鏡像拷貝到內存中。完成剩餘的與硬件平臺相關的初始化工做,好比文件系統,驅動模塊。最後啓動第一個用戶進程-init 進程並等待用戶進程的執行。
用戶空間的第一個進程init
- 1.2 zygote理解
- 在Android系統中,全部的應用程序進程以及系統服務進程SystemServer都是由Zygote進程孕育(fork)出來的。因爲Zygote進程在Android系統中有着如此重要的地位,本文將詳細分析它的啓動過程。---老羅
- android系統中建立java世界的盤古 建立新進程的女媧。 ---鄧凡平
二、Zygote進程如何啓動
- 2.1 init.zygote64_32.rc文件
- system/core/rootdir/init.zygote64_32.rc文件內容
-
1 service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote 2 class main 3 socket zygote stream 660 root system 4 onrestart write /sys/android_power/request_state wake 5 onrestart write /sys/power/state on 6 onrestart restart media 7 onrestart restart netd 8 9 service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary 10 class main 11 socket zygote_secondary stream 660 root system 12 onrestart restart zygote
- 2.2 查看ps信息
-
Zygote6四、Zygote是在init.rc中定義的服務進程,由init進程啓動,PPID均爲1。其中比較關鍵的vold、rild、surfaceflinger等關鍵進程也都是經過init進程啓動的。
-
LOCAL_MULTILIB: Android.mk中用來設置編譯爲32位或者64位的apk,so等
- 2.3 啓動
- Zygote process main(frameworks/base/cmds/app_process/app_main.cpp)
-
1 int main(int argc, char* const argv[]) 2 { 3 ... 121 if (zygote) { 122 runtime.start("com.android.internal.os.ZygoteInit", args); 123 } else if (className) { 124 runtime.start("com.android.internal.os.RuntimeInit", args); 125 } else { 126 fprintf(stderr, "Error: no class name or --zygote supplied.\n"); 127 app_usage(); 128 LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); 129 return 10; 130 } 131 }
-
將init.rc中指定的-Xzygote參數傳給JVM將進程的名字改成zygote(能夠回答前面的問題)執行AppRuntime類的start()方法,runtime.start(「com.android.internal.os.ZygoteInit」, true);
-
1 void AndroidRuntime::start(const char* className, const Vector<String8>& options) 2 { 3 ... 30 //const char* kernelHack = getenv("LD_ASSUME_KERNEL"); 31 //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack); 32 33 /* start the virtual machine */ 34 JniInvocation jni_invocation; 35 jni_invocation.Init(NULL); 36 JNIEnv* env; 37 if (startVm(&mJavaVM, &env) != 0) { 38 return; 39 } 40 onVmCreated(env); 41 42 /* 43 * Register android functions. 44 */ 45 if (startReg(env) < 0) { 46 ALOGE("Unable to register all android natives\n"); 47 return; 48 } 49 50 /* 51 * We want to call main() with a String array with arguments in it. 52 * At present we have two arguments, the class name and an option string. 53 * Create an array to hold them. 54 */ 55 jclass stringClass; 56 jobjectArray strArray; 57 jstring classNameStr; 58 59 stringClass = env->FindClass("java/lang/String"); 60 assert(stringClass != NULL); 61 strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); 62 assert(strArray != NULL); 63 classNameStr = env->NewStringUTF(className); 64 assert(classNameStr != NULL); 65 env->SetObjectArrayElement(strArray, 0, classNameStr); 66 67 for (size_t i = 0; i < options.size(); ++i) { 68 jstring optionsStr = env->NewStringUTF(options.itemAt(i).string()); 69 assert(optionsStr != NULL); 70 env->SetObjectArrayElement(strArray, i + 1, optionsStr); 71 } 72 73 /* 74 * Start VM. This thread becomes the main thread of the VM, and will 75 * not return until the VM exits. 76 */ 77 char* slashClassName = toSlashClassName(className); 78 jclass startClass = env->FindClass(slashClassName); 79 if (startClass == NULL) { 80 ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); 81 /* keep going */ 82 } else { 83 jmethodID startMeth = env->GetStaticMethodID(startClass, "main", 84 "([Ljava/lang/String;)V"); 85 if (startMeth == NULL) { 86 ALOGE("JavaVM unable to find main() in '%s'\n", className); 87 /* keep going */ 88 } else { 89 env->CallStaticVoidMethod(startClass, startMeth, strArray); 90 91 #if 0 92 if (env->ExceptionCheck()) 93 threadExitUncaughtException(env); 94 #endif 95 } 96 } 97 free(slashClassName); 98 99 ALOGD("Shutting down VM\n"); 100 if (mJavaVM->DetachCurrentThread() != JNI_OK) 101 ALOGW("Warning: unable to detach main thread\n"); 102 if (mJavaVM->DestroyJavaVM() != 0) 103 ALOGW("Warning: VM did not shut down cleanly\n"); 104 }
-
runtime.start函數,即在frameworks\base\core\jni\AndroidRuntime.cpp文件中
-
AndroidRuntime::startVm()中,設置一些虛擬機的參數後,經過JNI_CreateJavaVM()啓動虛擬機。
-
StartReg()註冊JNI 函數
-
env->CallStaticVoidMethod,調用ZygoteInit類的main()方法,正式進入到Java世界.
-
- frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
-
public static void main(String argv[]) { try { .... registerZygoteSocket(socketName); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); // Finish profiling the zygote initialization. SamplingProfilerIntegration.writeZygoteSnapshot(); // Do an initial gc to clean up after startup gc(); // Disable tracing so that forked processes do not inherit stale tracing tags from // Zygote. Trace.setTracingEnabled(false); if (startSystemServer) { startSystemServer(abiList, socketName); } Log.i(TAG, "Accepting command socket connections"); runSelectLoop(abiList); closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { Log.e(TAG, "Zygote died with exception", ex); closeServerSocket(); throw ex; } }
-
registerZygoteSocket,建立Socket服務端對象sServerSocket
preload方法預加載類,資源等
調用startSystemServer方法啓動系統服務system_server
runSelectLoopMode監聽和處理sServerSocket的Socket請求
- 三、Zygote做用
- 3.1 啓動system_server
-
1 /** 2 * Prepare the arguments and fork for the system server process. 3 */ 4 private static boolean startSystemServer(String abiList, String socketName) 5 throws MethodAndArgsCaller, RuntimeException { 6 ... 31 int pid; 32 33 try { 34 parsedArgs = new ZygoteConnection.Arguments(args); 35 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); 36 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); 37 38 /* Request to fork the system server process */ 39 pid = Zygote.forkSystemServer( 40 parsedArgs.uid, parsedArgs.gid, 41 parsedArgs.gids, 42 parsedArgs.debugFlags, 43 null, 44 parsedArgs.permittedCapabilities, 45 parsedArgs.effectiveCapabilities); 46 } catch (IllegalArgumentException ex) { 47 throw new RuntimeException(ex); 48 } 49 50 /* For child process */ 51 if (pid == 0) {//子進程進入 52 if (hasSecondZygote(abiList)) { 53 waitForSecondaryZygote(socketName); 54 } 55 56 handleSystemServerProcess(parsedArgs); 57 } 58 59 return true; 60 }
-
forkSystemServer,調用Native方法fork子進程經過forkSystemServer方法返回的值,進入兩個分支處理:父進程返回子進程pid值,進入到ZygoteInit類中的main方法繼續處理;而子進程調用handleSystemServerProcess方法,最終會運行system_server。
-
1 /** 2 * Finish remaining work for the newly forked system server process. 3 */ 4 private static void handleSystemServerProcess( 5 ZygoteConnection.Arguments parsedArgs) 6 throws ZygoteInit.MethodAndArgsCaller { 7 8 closeServerSocket();//子進程已經不是服務器了,因此關掉。 9 10 // set umask to 0077 so new files and directories will default to owner-only permissions. 11 Os.umask(S_IRWXG | S_IRWXO); 12 13 if (parsedArgs.niceName != null) { 14 Process.setArgV0(parsedArgs.niceName); 15 } 16 17 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); 18 if (systemServerClasspath != null) { 19 performSystemServerDexOpt(systemServerClasspath); 20 } 21 22 if (parsedArgs.invokeWith != null) { 23 String[] args = parsedArgs.remainingArgs; 24 // If we have a non-null system server class path, we'll have to duplicate the 25 // existing arguments and append the classpath to it. ART will handle the classpath 26 // correctly when we exec a new process. 27 if (systemServerClasspath != null) { 28 String[] amendedArgs = new String[args.length + 2]; 29 amendedArgs[0] = "-cp"; 30 amendedArgs[1] = systemServerClasspath; 31 System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length); 32 } 33 34 WrapperInit.execApplication(parsedArgs.invokeWith, 35 parsedArgs.niceName, parsedArgs.targetSdkVersion, 36 null, args); 37 } else { 38 ClassLoader cl = null; 39 if (systemServerClasspath != null) { 40 cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); 41 Thread.currentThread().setContextClassLoader(cl); 42 } 43 44 /* 45 * Pass the remaining arguments to SystemServer. 46 */ 47 RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); 48 } 49 50 /* should never reach here */ 51 }
- frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
-
43 public class RuntimeInit { 44 。。。 197 private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) 198 throws ZygoteInit.MethodAndArgsCaller { 199 。。。 232 throw new ZygoteInit.MethodAndArgsCaller(m, argv); 233 } 267 public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) 268 throws ZygoteInit.MethodAndArgsCaller { 269 if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); 270 271 redirectLogStreams(); 272 273 commonInit(); 274 nativeZygoteInit(); 275 276 applicationInit(targetSdkVersion, argv, classLoader); 277 } 297 private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) 298 throws ZygoteInit.MethodAndArgsCaller { 299 。。。 308 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); 309 VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); 310 311 。。。 320 // Remaining arguments are passed to the start class's static main 321 invokeStaticMain(args.startClass, args.startArgs, classLoader); 322 } 363 public static final IBinder getApplicationObject() { 364 return mApplicationObject; 365 }
425 } -
1 public static void main(String argv[]) { 2 try { 3 。。。 42 if (startSystemServer) { 43 startSystemServer(abiList, socketName); 44 } 45 。。。//然而並無機會進入循環
50 } catch (MethodAndArgsCaller caller) { 51 caller.run(); 52 } catch (RuntimeException ex) { 53 Log.e(TAG, "Zygote died with exception", ex); 54 closeServerSocket(); 55 throw ex; 56 } 57 } - 這個函數會執行兩個操做,一個是調用zygoteInitNative函數來執行一個Binder進程間通訊機制的初始化工做,這個工做完成以後,這個進 程中的Binder對象就能夠方便地進行進程間通訊了,另外一個是調用上面傳進來的com.android.server.SystemServer類的main函數。
- 3.2 查看與驗證Zygote啓動systemserver
- ps進程信息,驗證system_server是Zygote的分裂出的第一個子進程.
- 3.3 Zygote啓動其餘子進程
- 注意:重複的再也不涉及,咱們只是分析一下7-12吧。
- frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
-
1 /** 2 * Runs the zygote process's select loop. Accepts new connections as 3 * they happen, and reads commands from connections one spawn-request's 4 * worth at a time. 5 * 6 * @throws MethodAndArgsCaller in a child process when a main() should 7 * be executed. 8 */ 9 private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { 10 。。。
18 while (true) { 19 。。。 38 try { 39 fdArray = fds.toArray(fdArray); 40 index = selectReadable(fdArray); 41 } catch (IOException ex) { 42 throw new RuntimeException("Error in select()", ex); 43 } 44 45 if (index < 0) { 46 throw new RuntimeException("Error in select()"); 47 } else if (index == 0) { 48 ZygoteConnection newPeer = acceptCommandPeer(abiList); 49 peers.add(newPeer); 50 fds.add(newPeer.getFileDescriptor()); 51 } else { 52 boolean done; 53 done = peers.get(index).runOnce(); 54 55 if (done) { 56 peers.remove(index); 57 fds.remove(index); 58 } 59 } 60 } 61 } -
runSelectLoopMode中while(true)循環,接收到Socket請求後,會fork出子進程,子進程調用handleChildProc方法,最終拋出RuntimeInit.invokeStaticMain異常,退出while(true)循環(與fork Systemserver不同,後者沒有進入循環),進入到android.app.ActivityThread類的main方法執行;父進程調用handleParentProc方法,再次進入runSelectLoopMode中while(true)循環,準備接收下一個的請求事件。
- frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
-
1 boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { ... 37 try { 38 ...
105 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, 106 parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, 107 parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, 108 parsedArgs.appDataDir); 109 checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize"); 110 } catch (IOException ex) { 111 logAndPrintError(newStderr, "Exception creating pipe", ex); 112 } catch (ErrnoException ex) { 113 logAndPrintError(newStderr, "Exception creating pipe", ex); 114 } catch (IllegalArgumentException ex) { 115 logAndPrintError(newStderr, "Invalid zygote arguments", ex); 116 } catch (ZygoteSecurityException ex) { 117 logAndPrintError(newStderr, 118 "Zygote security policy prevents request: ", ex); 119 } 120 121 try { 122 if (pid == 0) { 123 // in child 124 IoUtils.closeQuietly(serverPipeFd); 125 serverPipeFd = null; 126 handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); 127 128 // should never get here, the child is expected to either 129 // throw ZygoteInit.MethodAndArgsCaller or exec(). 130 return true; 131 } else { 132 // in parent...pid of < 0 means failure 133 IoUtils.closeQuietly(childPipeFd); 134 childPipeFd = null; 135 return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); 136 } 137 } finally { 138 IoUtils.closeQuietly(childPipeFd); 139 IoUtils.closeQuietly(serverPipeFd); 140 } 141 } - 10和11略過,只是返回而已。咱們如今進入子進程的handleChildProc。
-
1 private void handleChildProc(Arguments parsedArgs, 2 FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) 3 throws ZygoteInit.MethodAndArgsCaller { 4 5 /** 6 * By the time we get here, the native code has closed the two actual Zygote 7 * socket connections, and substituted /dev/null in their place. The LocalSocket 8 * objects still need to be closed properly. 9 */ 10 11 closeSocket(); 12 ZygoteInit.closeServerSocket(); 13 14 。。。 55 if (parsedArgs.invokeWith != null) { 56 WrapperInit.execStandalone(parsedArgs.invokeWith, 57 parsedArgs.classpath, className, mainArgs); 58 } else { 59 ClassLoader cloader; 60 if (parsedArgs.classpath != null) { 61 cloader = new PathClassLoader(parsedArgs.classpath, 62 ClassLoader.getSystemClassLoader()); 63 } else { 64 cloader = ClassLoader.getSystemClassLoader(); 65 } 66 67 try { 68 ZygoteInit.invokeStaticMain(cloader, className, mainArgs); 69 } catch (RuntimeException ex) { 70 logAndPrintError(newStderr, "Error starting.", ex); 71 } 72 } 73 。。。 74 }
- 剩餘的就和上面雷同了,這裏再也不分析。
- 3.1 啓動system_server
四、總結
- 系統啓動時init進程會建立Zygote進程,Zygote進程負責後續Android應用程序框架層的其它進程的建立和啓動工做。(可使用ps查看)
Zygote進程會首先建立一個SystemServer進程,SystemServer進程負責啓動系統的關鍵服務,如包管理服務PackageManagerService和應用程序組件管理服務ActivityManagerService。
當咱們須要啓動一個Android應用程序時,ActivityManagerService會經過Socket進程間通訊機制,通知Zygote進程爲這個應用程序建立一個新的進程。