Android系统进程Zygote启动过程的源代码分析(3)
Step 5. ZygoteInit.startSystemServer
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
- public class ZygoteInit {
- ......
- private static boolean startSystemServer()
- throws MethodAndArgsCaller, RuntimeException {
- /* 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,3001,3002,3003",
- "--capabilities=130104352,130104352",
- "--runtime-init",
- "--nice-name=system_server",
- "com.android.server.SystemServer",
- };
- ZygoteConnection.Arguments parsedArgs = null;
- int pid;
- try {
- parsedArgs = new ZygoteConnection.Arguments(args);
- ......
- /* Request to fork the system server process */
- pid = Zygote.forkSystemServer(
- parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, debugFlags, null,
- parsedArgs.permittedCapabilities,
- parsedArgs.effectiveCapabilities);
- } catch (IllegalArgumentException ex) {
- ......
- }
- /* For child process */
- if (pid == 0) {
- handleSystemServerProcess(parsedArgs);
- }
- return true;
- }
- ......
- }
这里我们可以看到,Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。
Step 6. ZygoteInit.handleSystemServerProcess
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
- 这里我们可以看到,Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。
- Step 6. ZygoteInit.handleSystemServerProcess
- 这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
由于由Zygote进程创建的子进程会继承Zygote进程在前面Step 4中创建的Socket文件描述符,而这里的子进程又不会用到它,因此,这里就调用closeServerSocket函数来关闭它。这个函数接着调用RuntimeInit.zygoteInit函数来进一步执行启动SystemServer组件的操作。
Step 7. RuntimeInit.zygoteInit
这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
- public class RuntimeInit {
- ......
- public static final void zygoteInit(String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
- ......
- zygoteInitNative();
- ......
- // Remaining arguments are passed to the start class's static main
- String startClass = argv[curArg++];
- String[] startArgs = new String[argv.length - curArg];
- System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
- invokeStaticMain(startClass, startArgs);
- }
- ......
- }
这个函数会执行两个操作,一个是调用zygoteInitNative函数来执行一个Binder进程间通信机制的初始化工作,这个工作完成之后,这个进程中的Binder对象就可以方便地进行进程间通信了,另一个是调用上面Step 5传进来的com.android.server.SystemServer类的main函数。
Step 8. RuntimeInit.zygoteInitNative
这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
- public class RuntimeInit {
- ......
- public static final native void zygoteInitNative();
- ......
- }
这里可以看出,函数zygoteInitNative是一个Native函数,实现在frameworks/base/core/jni/AndroidRuntime.cpp文件中,这里我们就不再细看了,具体可以参考Android应用程序进程启动过程的源代码分析一文的Step 9,完成这一步后,这个进程的Binder进程间通信机制基础设施就准备好了。
回到Step 7中的RuntimeInit.zygoteInitNative函数,下一步它就要执行com.android.server.SystemServer类的main函数了。
Step 9. SystemServer.main
这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:
- public class SystemServer
- {
- ......
- native public static void init1(String[] args);
- ......
- public static void main(String[] args) {
- ......
- init1(args);
- ......
- }
- public static final void init2() {
- Slog.i(TAG, "Entered the Android system server!");
- Thread thr = new ServerThread();
- thr.setName("android.server.ServerThread");
- thr.start();
- }
- ......
- }
这里的main函数首先会执行JNI方法init1,然后init1会调用这里的init2函数,在init2函数里面,会创建一个ServerThread线程对象来执行一些系统关键服务的启动操作,例如我们在前面两篇文章Android应用程序安装过程源代码分析和Android系统默认Home应用程序(Launcher)的启动过程源代码分析中提到的PackageManagerService和ActivityManagerService。
这一步的具体执行过程可以参考Android应用程序安装过程源代码分析一文,这里就不再详述了。
这里执行完成后,层层返回,最后回到上面的Step 3中的ZygoteInit.main函数中,接下来它就要调用runSelectLoopMode函数进入一个无限循环在前面Step 4中创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程了。
Step 10. ZygoteInit.runSelectLoopMode
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
- public class ZygoteInit {
- ......
- private static void runSelectLoopMode() throws MethodAndArgsCaller {
- ArrayList<FileDescriptor> fds = new ArrayList();
- ArrayList<ZygoteConnection> peers = new ArrayList();
- FileDescriptor[] fdArray = new FileDescriptor[4];
- fds.add(sServerSocket.getFileDescriptor());
- peers.add(null);
- int loopCount = GC_LOOP_COUNT;
- while (true) {
- int index;
- ......
- try {
- fdArray = fds.toArray(fdArray);
- index = selectReadable(fdArray);
- } catch (IOException ex) {
- throw new RuntimeException("Error in select()", ex);
- }
- if (index < 0) {
- throw new RuntimeException("Error in select()");
- } else if (index == 0) {
- ZygoteConnection newPeer = acceptCommandPeer();
- peers.add(newPeer);
- fds.add(newPeer.getFileDesciptor());
- } else {
- boolean done;
- done = peers.get(index).runOnce();
- if (done) {
- peers.remove(index);
- fds.remove(index);
- }
- }
- }
- }
- ......
- }
这个函数我们已经在Android应用程序进程启动过程的源代码分析一文的Step 5中分析过了,这就是在等待ActivityManagerService来连接这个Socket,然后调用ZygoteConnection.runOnce函数来创建新的应用程序,有兴趣的读者可以参考Android应用程序进程启动过程的源代码分析这篇文章,这里就不再详述了。
这样,Zygote进程就启动完成了,学习到这里,我们终于都对Android系统中的进程有了一个深刻的认识了,这里总结一下:
1. 系统启动时init进程会创建Zygote进程,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作。
2. Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService。
3. 当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程。
Android系统进程Zygote启动过程的源代码分析(3)相关推荐
- Android系统进程Zygote启动过程的源代码分析
原文地址:http://blog.csdn.net/luoshengyang/article/details/6747696 Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口 ...
- Android应用程序进程启动过程的源代码分析(1)
Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制:这两个特点都是在进程的初始化过程中实 ...
- Android应用程序进程启动过程的源代码分析(2)
Step 5. ZygoteInit.runSelectLoopMode 这个函数定义在frameworks/base/core/java/com/android/internal ...
- Android 新建一个APP进程的源代码分析(ActivityManageService->Zygote->ActivityThread)
Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制:这两个特点都是在进程的初始化过程中实 ...
- Android系统的启动过程
Android系统的启动过程可以简单地总结为以下几个流程: 加载BootLoader -> 初始化内核 -> 启动init进程 -> init进程fork出Zygote(孵化器)进程 ...
- Android 中View的绘制机制源代码分析 三
到眼下为止,measure过程已经解说完了,今天開始我们就来学习layout过程.只是在学习layout过程之前.大家有没有发现我换了编辑器,哈哈.最终下定决心从Html编辑器切换为markdown编 ...
- android服务的启动过程,Android Service的启动过程(上)
原标题:Android Service的启动过程(上) (点击上方公众号,可快速关注) 来源:伯乐在线专栏作者 - xuyinhuan 链接:http://android.jobbole.com/85 ...
- Android 解锁屏启动过程
Android 解锁屏启动过程 一. 开机启动 在开机过程中无线模块初始化时获取SIM卡,状态.在初始化完成后调用vm.systemReady()函数通知进入相应的Lock Screen进行解锁. 1 ...
- Android应用程序启动过程源代码分析(5)
Step 35. MainActivity.onCreate 这个函数定义在packages/experimental/Activity/src/shy/luo/activity/MainActivi ...
最新文章
- python 打开文件-Python open()文件处理使用介绍
- iOS从零开始学习直播之音频2.后台播放和在线播放
- Qt 5 打包成一个单文件方法,可以在其他电脑运行(附资源)
- Django路由分发
- Spark MLlib实现的广告点击预测–Gradient-Boosted Trees
- 【Java】分享一个诡异的可见性问题
- apache、nginx验证
- 程序员初学者参考 ---懂得基础语法后如何做一个自己的case?
- linux驱动下载中心,Kvaser Linux驱动程序| Linux驱动程序和SDK开发包
- 关于Qt的无边框窗口移动
- 布局万花筒:UIColletionview
- uni-app学习笔记
- 安装snipe-IT遇到的php问题
- File Storage:文件存储
- 新一代iPad mini曝光:屏幕变大、颜值大幅提升!
- java cause_Cause: java.lang.UnsupportedOperationException
- 【输入法】搜狗输入法中英文切换
- dockers 的简单使用
- ijkplayer使用ffmpeg为视频添加水印avfilter_graph_parse_ptr返回Invalid data found when processing input
- pki与其他人交流时的 机密性 完整性 身份验证 的整个过程
热门文章
- “木马源”攻击影响多数编程语言的编译器,将在软件供应链攻击中发挥巨大作用...
- 推进 DevSecOps 走向未来
- gitlab 邮件发送
- 腾讯云centos7下搭建fastDFS+nginx
- 2018年《DevOps 现状报告》新鲜出炉:行业脉动与团队发展指导一览
- SQL Server打开数据表中的XML内容时报错的解决办法
- thinkphp3.2 不同域名配置不同分组设置
- IDEA 忽略CSS错误
- 一句话让你明白伪元素和伪类的区别
- 完美解决:此地址使用了一个通常用于网络浏览以外目的的端口.出于安全原因,Firefox 取消了该请求...