Zygote進(jìn)程簡(jiǎn)介
什么是Zygote進(jìn)程? Zygote進(jìn)程 是整個(gè)Android系統(tǒng)的根進(jìn)程力九,包括SystemServer進(jìn)程和所有應(yīng)用進(jìn)程在內(nèi)都是通過Zygote進(jìn)程 fork 出來的谍倦。Zygote進(jìn)程則是通過Linux系統(tǒng)init進(jìn)程啟動(dòng)塞赂。
- 啟動(dòng)順序: Linux系統(tǒng)init進(jìn)程 --> Zygote進(jìn)程 --> SystemServer進(jìn)程 --> Application 進(jìn)程
- init進(jìn)程:Android系統(tǒng)第一個(gè)進(jìn)程,也是linux的根進(jìn)程昼蛀,主要用于初始化各種文件系統(tǒng)宴猾,輸入輸出系統(tǒng),log系統(tǒng)等等設(shè)備相關(guān)聯(lián)的初始化
- Zygote進(jìn)程:Android系統(tǒng)的根進(jìn)城叼旋,用于fork除SystemServer進(jìn)程和各種應(yīng)用進(jìn)程
- SystemServer進(jìn)程 --> 啟動(dòng)ActivityManagerService,WindowManagerService,PowerManagerService等等各項(xiàng)服務(wù)
- Application 進(jìn)程: App 應(yīng)用進(jìn)程
源碼分析(Android 6.0)
- 1.從ZygoteInit main()方法中開始看仇哆。
public static void main(String argv[]) {
try {
RuntimeInit.enableDdms();
// 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]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
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
gcAndFinalize();
// 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;
}
}
-
從上面可以看到主要做了哪幾件事
1.1 enableDdms() 設(shè)置DDMS可用
1.2 for 循環(huán),解析是否需要啟動(dòng)SystemService進(jìn)程夫植;獲取abi列表讹剔;獲取socket連接名稱
-
1.3 registerZygoteSocket(String socketName) 為Zygote 進(jìn)程注冊(cè)socket;(PS:Android中進(jìn)程間通都是用Binder,但是有一個(gè)例外,SystemService進(jìn)程與Zygote進(jìn)程之間是通過Socket的方式進(jìn)行通訊的)
private static void registerZygoteSocket(String socketName) { if (sServerSocket == null) { int fileDesc; final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { throw new RuntimeException(fullSocketName + " unset or invalid", ex); } try { FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); sServerSocket = new LocalServerSocket(fd); } catch (IOException ex) { throw new RuntimeException( "Error binding to local socket '" + fileDesc + "'", ex); } } }
-
1.4 preload(),可以看到
preloadClasses 初始化Zygote所需的類
preloadResources 初始化通用系統(tǒng)資源
preloadOpenGL 初始化OpenGL
preloadSharedLibraries 初始化 shared libraries
preloadTextResources 初始化文字資源
prepareWebViewInZygote 初始化WebView(必須是Zygote進(jìn)程)static void preload() { Log.d(TAG, "begin preload"); preloadClasses(); preloadResources(); preloadOpenGL(); preloadSharedLibraries(); preloadTextResources(); // Ask the WebViewFactory to do any initialization that must run in the zygote process, // for memory sharing purposes. WebViewFactory.prepareWebViewInZygote(); Log.d(TAG, "end preload"); }
1.5 SamplingProfilerIntegration.writeZygoteSnapshot() 存儲(chǔ)一下zygote進(jìn)程快照
gcAndFinalize() fork之前調(diào)用下系統(tǒng)GC1.6 startSystemServer(abiList, socketName)辟拷,接下來就是fork SystemServer進(jìn)程了
通過Zygote.forkSystemServe() fork 出SystemServer進(jìn)程1.7 關(guān)閉Socket
handleSystemServerProcess 當(dāng)fork出SystemServer后關(guān)閉socket
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 ); /* Hardcoded command line to start the system server */ 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", "--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 */ 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 */ if (pid == 0) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } handleSystemServerProcess(parsedArgs); } return true; } /** * Finish remaining work for the newly forked system server process. */ private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket(); // set umask to 0077 so new files and directories will default to owner-only permissions. 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 we have a non-null system server class path, we'll have to duplicate the // existing arguments and append the classpath to it. ART will handle the classpath // correctly when we exec a new process. 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, VMRuntime.getCurrentInstructionSet(), null, args); } else { ClassLoader cl = null; if (systemServerClasspath != null) { cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(cl); } /* * Pass the remaining arguments to SystemServer. */ RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } /* should never reach here */ }
### 梳理一下流程
![流程圖](https://github.com/jfson/ImgResource/blob/master/13.png?raw=true)