Android源码(1) --- Zygote进程启动流程
来源:互联网 发布:学mysql还是sql server 编辑:程序博客网 时间:2024/05/22 10:41
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()方法中开始看。
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() 设置DDMS可用
1.2 for 循环,解析是否需要启动SystemService进程;获取abi列表;获取socket连接名称
1.3 registerZygoteSocket(String socketName) 为Zygote 进程注册socket;(PS:Android中进程间通都是用Binder,但是有一个例外,SystemService进程与Zygote进程之间是通过Socket的方式进行通讯的)
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 初始化通用系统资源
preloadOpenGL 初始化OpenGL
preloadSharedLibraries 初始化 shared libraries
preloadTextResources 初始化文字资源
prepareWebViewInZygote 初始化WebView(必须是Zygote进程)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() 存储一下zygote进程快照
gcAndFinalize() fork之前调用下系统GC - 1.6 startSystemServer(abiList, socketName),接下来就是fork SystemServer进程了
通过Zygote.forkSystemServe() fork 出SystemServer进程 - 1.7 关闭Socket
handleSystemServerProcess 当fork出SystemServer后关闭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 */ }
梳理一下流程
阅读全文
0 0
- Android源码(1) --- Zygote进程启动流程
- Android源码解析之(八)-->Zygote进程启动流程
- Android源码解析之(八)-->Zygote进程启动流程
- Android源码基础解析之Zygote进程启动流程
- Zygote进程启动流程
- Android系统进程Zygote启动流程
- Android Zygote启动流程源码解析
- Android Zygote启动流程源码解析
- Android zygote启动流程
- Android zygote进程启动
- Zygote进程的启动流程
- Android系统启动流程(二)解析Zygote进程启动过程
- Android runtime机制(二)zygote进程的启动流程
- Android系统zygote进程启动过程源码分析
- Android Zygote 进程的启动
- Android Zygote进程启动过程
- Android Zygote进程启动过程
- android源码阅读-----zygote进程
- Android 项目构建过程
- Java中this关键字用法
- CVPR 2017 Abstracts Collection
- Hive开发UDF
- NLTK使用总结
- Android源码(1) --- Zygote进程启动流程
- C#程序退出的几种方法
- [刷题]Codeforces Round #412(Div. 2)
- CentOS7使用oneinstack安装全能环境
- Maven初体验
- Android源码(2) --- SystemServer进程启动流程
- Mac安装hadoop伪分布式
- 提高网站流量转化率需要分析的三个指标和要做的两个方面
- USACO-Section1.4 milk3[深搜]