Zygote进程简介
什么是Zygote进程? Zygote进程 是整个Android系统的根进程,包括SystemServer进程和所有应用进程在内都是通过Zygote进程 fork 出来的。Zygote进程则是通过Linux系统init进程启动。
- 启动顺序: Linux系统init进程 –> Zygote进程 –> SystemServer进程 –> Application 进程
- init进程:Android系统第一个进程,也是linux的根进程,主要用于初始化各种文件系统,输入输出系统,log系统等等设备相关联的初始化
- Zygote进程:Android系统的根进城,用于fork除SystemServer进程和各种应用进程
- SystemServer进程 –> 启动ActivityManagerService,WindowManagerService,PowerManagerService等等各项服务
- Application 进程: App 应用进程
源码分析(Android 6.0)
- 1.从ZygoteInit main()方法中开始看。
|
|
从上面可以看到主要做了哪几件事
1.1 enableDdms() 设置DDMS可用
1.2 for 循环,解析是否需要启动SystemService进程;获取abi列表;获取socket连接名称
1.3 registerZygoteSocket(String socketName) 为Zygote 进程注册socket;(PS:Android中进程间通都是用Binder,但是有一个例外,SystemService进程与Zygote进程之间是通过Socket的方式进行通讯的)
123456789101112131415161718192021private 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 初始化通用系统资源
preloadOpenGL 初始化OpenGL
preloadSharedLibraries 初始化 shared libraries
preloadTextResources 初始化文字资源
prepareWebViewInZygote 初始化WebView(必须是Zygote进程)123456789101112static 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() 存储一下zygote进程快照
gcAndFinalize() fork之前调用下系统GC- 1.6 startSystemServer(abiList, socketName),接下来就是fork SystemServer进程了
通过Zygote.forkSystemServe() fork 出SystemServer进程 1.7 关闭Socket
handleSystemServerProcess 当fork出SystemServer后关闭socket123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110private 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 */}