Step 5. ZygoteInit.startSystemServer
       这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

  1. public class ZygoteInit {
  2. ......
  3. private static boolean startSystemServer()
  4. throws MethodAndArgsCaller, RuntimeException {
  5. /* Hardcoded command line to start the system server */
  6. String args[] = {
  7. "--setuid=1000",
  8. "--setgid=1000",
  9. "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
  10. "--capabilities=130104352,130104352",
  11. "--runtime-init",
  12. "--nice-name=system_server",
  13. "com.android.server.SystemServer",
  14. };
  15. ZygoteConnection.Arguments parsedArgs = null;
  16. int pid;
  17. try {
  18. parsedArgs = new ZygoteConnection.Arguments(args);
  19. ......
  20. /* Request to fork the system server process */
  21. pid = Zygote.forkSystemServer(
  22. parsedArgs.uid, parsedArgs.gid,
  23. parsedArgs.gids, debugFlags, null,
  24. parsedArgs.permittedCapabilities,
  25. parsedArgs.effectiveCapabilities);
  26. } catch (IllegalArgumentException ex) {
  27. ......
  28. }
  29. /* For child process */
  30. if (pid == 0) {
  31. handleSystemServerProcess(parsedArgs);
  32. }
  33. return true;
  34. }
  35. ......
  36. }

这里我们可以看到,Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。

Step 6. ZygoteInit.handleSystemServerProcess
  这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

  1. 这里我们可以看到,Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。
  2. Step 6. ZygoteInit.handleSystemServerProcess
  3. 这个函数定义在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文件中:

  1. public class RuntimeInit {
  2. ......
  3. public static final void zygoteInit(String[] argv)
  4. throws ZygoteInit.MethodAndArgsCaller {
  5. ......
  6. zygoteInitNative();
  7. ......
  8. // Remaining arguments are passed to the start class's static main
  9. String startClass = argv[curArg++];
  10. String[] startArgs = new String[argv.length - curArg];
  11. System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
  12. invokeStaticMain(startClass, startArgs);
  13. }
  14. ......
  15. }

这个函数会执行两个操作,一个是调用zygoteInitNative函数来执行一个Binder进程间通信机制的初始化工作,这个工作完成之后,这个进程中的Binder对象就可以方便地进行进程间通信了,另一个是调用上面Step 5传进来的com.android.server.SystemServer类的main函数。

Step 8. RuntimeInit.zygoteInitNative
这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

  1. public class RuntimeInit {
  2. ......
  3. public static final native void zygoteInitNative();
  4. ......
  5. }

这里可以看出,函数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文件中:

  1. public class SystemServer
  2. {
  3. ......
  4. native public static void init1(String[] args);
  5. ......
  6. public static void main(String[] args) {
  7. ......
  8. init1(args);
  9. ......
  10. }
  11. public static final void init2() {
  12. Slog.i(TAG, "Entered the Android system server!");
  13. Thread thr = new ServerThread();
  14. thr.setName("android.server.ServerThread");
  15. thr.start();
  16. }
  17. ......
  18. }

这里的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文件中:

  1. public class ZygoteInit {
  2. ......
  3. private static void runSelectLoopMode() throws MethodAndArgsCaller {
  4. ArrayList<FileDescriptor> fds = new ArrayList();
  5. ArrayList<ZygoteConnection> peers = new ArrayList();
  6. FileDescriptor[] fdArray = new FileDescriptor[4];
  7. fds.add(sServerSocket.getFileDescriptor());
  8. peers.add(null);
  9. int loopCount = GC_LOOP_COUNT;
  10. while (true) {
  11. int index;
  12. ......
  13. try {
  14. fdArray = fds.toArray(fdArray);
  15. index = selectReadable(fdArray);
  16. } catch (IOException ex) {
  17. throw new RuntimeException("Error in select()", ex);
  18. }
  19. if (index < 0) {
  20. throw new RuntimeException("Error in select()");
  21. } else if (index == 0) {
  22. ZygoteConnection newPeer = acceptCommandPeer();
  23. peers.add(newPeer);
  24. fds.add(newPeer.getFileDesciptor());
  25. } else {
  26. boolean done;
  27. done = peers.get(index).runOnce();
  28. if (done) {
  29. peers.remove(index);
  30. fds.remove(index);
  31. }
  32. }
  33. }
  34. }
  35. ......
  36. }

这个函数我们已经在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)相关推荐

  1. Android系统进程Zygote启动过程的源代码分析

    原文地址:http://blog.csdn.net/luoshengyang/article/details/6747696 Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口 ...

  2. Android应用程序进程启动过程的源代码分析(1)

    Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制:这两个特点都是在进程的初始化过程中实 ...

  3. Android应用程序进程启动过程的源代码分析(2)

      Step 5. ZygoteInit.runSelectLoopMode         这个函数定义在frameworks/base/core/java/com/android/internal ...

  4. Android 新建一个APP进程的源代码分析(ActivityManageService->Zygote->ActivityThread)

    Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制:这两个特点都是在进程的初始化过程中实 ...

  5. Android系统的启动过程

    Android系统的启动过程可以简单地总结为以下几个流程: 加载BootLoader -> 初始化内核 -> 启动init进程 -> init进程fork出Zygote(孵化器)进程 ...

  6. Android 中View的绘制机制源代码分析 三

    到眼下为止,measure过程已经解说完了,今天開始我们就来学习layout过程.只是在学习layout过程之前.大家有没有发现我换了编辑器,哈哈.最终下定决心从Html编辑器切换为markdown编 ...

  7. android服务的启动过程,Android Service的启动过程(上)

    原标题:Android Service的启动过程(上) (点击上方公众号,可快速关注) 来源:伯乐在线专栏作者 - xuyinhuan 链接:http://android.jobbole.com/85 ...

  8. Android 解锁屏启动过程

    Android 解锁屏启动过程 一. 开机启动 在开机过程中无线模块初始化时获取SIM卡,状态.在初始化完成后调用vm.systemReady()函数通知进入相应的Lock Screen进行解锁. 1 ...

  9. Android应用程序启动过程源代码分析(5)

    Step 35. MainActivity.onCreate 这个函数定义在packages/experimental/Activity/src/shy/luo/activity/MainActivi ...

最新文章

  1. python 打开文件-Python open()文件处理使用介绍
  2. iOS从零开始学习直播之音频2.后台播放和在线播放
  3. Qt 5 打包成一个单文件方法,可以在其他电脑运行(附资源)
  4. Django路由分发
  5. Spark MLlib实现的广告点击预测–Gradient-Boosted Trees
  6. 【Java】分享一个诡异的可见性问题
  7. apache、nginx验证
  8. 程序员初学者参考 ---懂得基础语法后如何做一个自己的case?
  9. linux驱动下载中心,Kvaser Linux驱动程序| Linux驱动程序和SDK开发包
  10. 关于Qt的无边框窗口移动
  11. 布局万花筒:UIColletionview
  12. uni-app学习笔记
  13. 安装snipe-IT遇到的php问题
  14. File Storage:文件存储
  15. 新一代iPad mini曝光:屏幕变大、颜值大幅提升!
  16. java cause_Cause: java.lang.UnsupportedOperationException
  17. 【输入法】搜狗输入法中英文切换
  18. dockers 的简单使用
  19. ijkplayer使用ffmpeg为视频添加水印avfilter_graph_parse_ptr返回Invalid data found when processing input
  20. pki与其他人交流时的 机密性 完整性 身份验证 的整个过程

热门文章

  1. “木马源”攻击影响多数编程语言的编译器,将在软件供应链攻击中发挥巨大作用...
  2. 推进 DevSecOps 走向未来
  3. gitlab 邮件发送
  4. 腾讯云centos7下搭建fastDFS+nginx
  5. 2018年《DevOps 现状报告》新鲜出炉:行业脉动与团队发展指导一览
  6. SQL Server打开数据表中的XML内容时报错的解决办法
  7. thinkphp3.2 不同域名配置不同分组设置
  8. IDEA 忽略CSS错误
  9. 一句话让你明白伪元素和伪类的区别
  10. 完美解决:此地址使用了一个通常用于网络浏览以外目的的端口.出于安全原因,Firefox 取消了该请求...