《android framework常用api源码分析》之Zygote进程
来源:互联网 发布:数据挖掘 招聘 长沙 编辑:程序博客网 时间:2024/06/05 04:53
《android framework常用api源码分析》android生态在中国已经发展非常庞大了,一方面是因为手机移动端的覆盖,另一方面是从事android开发的人也月来越多。那么用人单位对android要求也变了,对android不仅要熟练使用而且要懂得原理。而就程序员自身阅读源码有什么那些?这里我通过自己理解归纳了一下。
提高程序执行效率,正确理解api可以高效使用,优化内存和执行效率。
避免八阿哥强势逆袭,android开发同学都知道android找bug比较麻烦,尤其是一下jni底层调用错误信息不够明确地方更加难找。
帮助自己写出优雅的代码,开发需要规范,而源码中有很多优秀的谷歌规范。
优秀的设计模式,帮助自己提升程序造诣。
黑科技,通过反射高一些api不能够达到的功能,例如插件化、热更新。
上面是简单个人理解,有更多补充欢迎留言。所以这里准备出一个系列的文章来分析android framework api, 这些文章也是来自整理于网络,所以要感谢那些具有分享精神的大神们。
文章目录:
- apk 打包过程解析。
- handler 消息机制。
- AsyncTask 异步任务。
- HandlerThread handler线程。
- IntentService意图服务。
- Zygote进程。
- SystemServer进程。
- Launcher 程序。
- app 进程启动流程。
- 系统app启动安装流程。
- app应用安装流程。
- Activity启动流程。
- LruCache内存缓存
Zygote进程是什么?
Zygote进程是android系统启动的第一个进程(不包括kernel层次的init进程),是所有的android进程的父进程,是一个根进程,包括SystemServer和各种应用进程都是通过Zygote进程fork出来的。Zygote(孵化)进程相当于是android系统的根进程,后面所有的进程都是通过这个进程fork出来的,而Zygote进程则是通过linux系统的init进程启动的,也就是说,android系统中各种进程的启动方式
init进程 –> Zygote进程 –> SystemServer进程 –>各种应用进程
init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;
Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;
SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;
各种应用进程:启动自己编写的客户端应用时,一般都是重新启动一个应用进程,有自己的虚拟机与运行环境;
本文主要介绍一下Zygote进程的启动流程,关于SystenServer进程和各种应用进程的启动方式会在以后的文章中介绍。
init进程在启动Zygote进程时一般都会调用ZygoteInit类的main方法,因此我们这里看一下该方法的具体实现(基于android23源码);
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; } }
第一行主要是调用enableDdms(),设置DDMS可用,可以发现DDMS启动的时机还是比较早的,在整个Zygote进程刚刚开始要启动额时候就设置可用了。
下面的循环主要是解析main方法的参数获取是否需要启动SystemService进程,获取abi列表,获取scoket连接名称
(这里需要注意的是:android系统中进程之间通讯的方式是Binder,但是有一个例外是SystemService进程与Zygote进程之间是通过Socket的方式进行通讯的)然后调用registerZygoteSocket(String socketName)为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); } } }
- 接着调用系统方法preLoad()
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"); }
这其中:
preloadClasses()用于初始化Zygote中需要的class类;
preloadResources()用于初始化系统资源;
preloadOpenGL()用于初始化OpenGL;
preloadSharedLibraries()用于初始化系统libraries;
preloadTextResources()用于初始化文字资源;
prepareWebViewInZygote()用于初始化webview;
- 然后调用startSystemServer(abiList, 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; }
可以看到这段逻辑的执行逻辑就是通过Zygote fork出SystemServer进程。
总结:
Zygote进程mian方法主要执行逻辑:
初始化DDMS;
注册Zygote进程的socket通讯;
初始化Zygote中的各种类,资源文件,OpenGL,类库,Text资源等等;
初始化完成之后fork出SystemServer进程;
fork出SystemServer进程之后,关闭socket连接;
- 《android framework常用api源码分析》之Zygote进程
- 《android framework常用api源码分析》之SystemServer进程
- Android Zygote进程源码分析
- Android Zygote进程源码分析
- 《android framework常用api源码分析》之app 进程启动流程
- 《android framework常用api源码分析》之handler消息机制
- 《android framework常用api源码分析》之AsyncTask异步任务
- 《android framework常用api源码分析》之HandlerThread handler线程
- 《android framework常用api源码分析》之IntentService意图服务
- 《android framework常用api源码分析》之LruCache内存缓存
- 《android framework常用api源码分析》之Launcher 程序
- 《android framework常用api源码分析》之Activity启动流程
- Android源码分析--Zygote进程分析
- Zygote进程源码分析之二
- Android Zygote源码分析
- Android Framework学习(二)之Zygote进程启动解析
- android6.0源码分析之Zygote进程分析
- android6.0源码分析之Zygote进程分析
- 极客先锋 Linux 下的dd命令使用详解(摘录)
- 记一次properties的坑
- BackgroundWorker
- 入门Vue2.0及学习实战项目
- leetcode 462. Minimum Moves to Equal Array Elements II
- 《android framework常用api源码分析》之Zygote进程
- 配置Pycharm开发模板
- 【教育自救】 你准备好面对逼迫了吗
- zookeeper的zkCli.sh命令行使用方法
- 二战时图灵机破译的Enigma密码,现在AI仅需13分钟便可破译
- ChromeDriver can't do file uploads if file input not clickable
- centos7系统下使用yum命令被锁定
- 浏览器同源政策及其规避方法
- 记一次tomcat参数调试