在ZygoteInit的main()方法中做了几件大事,其中一件便是启动Systemserver进程,代码如下:

@/frameworks/base/core/Java/com/Android/internal/os/ZygoteInit.java

  1. public static void main(String argv[]) {
  2. try {
  3. ......
  4. if (argv[1].equals("start-system-server")) {
  5. startSystemServer();//启动system_server进程
  6. } else if (!argv[1].equals("")) {
  7. throw new RuntimeException(argv[0] + USAGE_STRING);
  8. }
  9. ......
  10. }

startSystemServer方法的实现如下:

@/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

  1. /**
  2. * Prepare the arguments and fork for the system server process.
  3. */
  4. private static boolean startSystemServer()
  5. throws MethodAndArgsCaller, RuntimeException {
  6. long capabilities = posixCapabilitiesAsBits(
  7. OsConstants.CAP_KILL,
  8. OsConstants.CAP_NET_ADMIN,
  9. OsConstants.CAP_NET_BIND_SERVICE,
  10. OsConstants.CAP_NET_BROADCAST,
  11. OsConstants.CAP_NET_RAW,
  12. OsConstants.CAP_SYS_MODULE,
  13. OsConstants.CAP_SYS_NICE,
  14. OsConstants.CAP_SYS_RESOURCE,
  15. OsConstants.CAP_SYS_TIME,
  16. OsConstants.CAP_SYS_TTY_CONFIG
  17. );
  18. /* Hardcoded command line to start the system server */
  19. String args[] = {
  20. "--setuid=1000",
  21. "--setgid=1000",
  22. "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
  23. "--capabilities=" + capabilities + "," + capabilities,
  24. "--runtime-init",
  25. "--nice-name=system_server",
  26. "com.android.server.SystemServer",
  27. };
  28. ZygoteConnection.Arguments parsedArgs = null;
  29. int pid;
  30. try {
  31. parsedArgs = new ZygoteConnection.Arguments(args);
  32. ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
  33. ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
  34. /* Request to fork the system server process */
  35. pid = Zygote.forkSystemServer(//以fork的方式创建system_server进程
  36. parsedArgs.uid, parsedArgs.gid,
  37. parsedArgs.gids,
  38. parsedArgs.debugFlags,
  39. null,
  40. parsedArgs.permittedCapabilities,
  41. parsedArgs.effectiveCapabilities);
  42. } catch (IllegalArgumentException ex) {
  43. throw new RuntimeException(ex);
  44. }
  45. /* For child process */
  46. if (pid == 0) {//pid==0说明在子进程中,父进程为Zygote
  47. handleSystemServerProcess(parsedArgs);
  48. }
  49. return true;
  50. }

在startSystemServer中先设置了fork SystemServer所需的参数,然后通过forkSystemServer方法fork出SystemServer进程,最后通过handleSystemServerProcess处理新进程中的善后事宜。

首先看一下参数:

1、setuid=1000,这里1000代表SYSTEM_UID,即系统进程,关于进程ID的说明可以参见:/frameworks/base/core/java/android/os/Process.java。

2、nice-name=system_server表示制定进程的名字为“system_server”

3、com.android.server.SystemServer表示SystemServer类的位置。

接下来看一下forkSystemServer的实现:

@/libcore/dalvik/src/main/java/dalvik/system/Zygote.java

  1. /**
  2. * Special method to start the system server process. In addition to the
  3. * common actions performed in forkAndSpecialize, the pid of the child
  4. * process is recorded such that the death of the child process will cause
  5. * zygote to exit.
  6. *
  7. * @param uid the UNIX uid that the new process should setuid() to after
  8. * fork()ing and and before spawning any threads.
  9. * @param gid the UNIX gid that the new process should setgid() to after
  10. * fork()ing and and before spawning any threads.
  11. * @param gids null-ok; a list of UNIX gids that the new process should
  12. * setgroups() to after fork and before spawning any threads.
  13. * @param debugFlags bit flags that enable debugging features.
  14. * @param rlimits null-ok an array of rlimit tuples, with the second
  15. * dimension having a length of 3 and representing
  16. * (resource, rlim_cur, rlim_max). These are set via the posix
  17. * setrlimit(2) call.
  18. * @param permittedCapabilities argument for setcap()
  19. * @param effectiveCapabilities argument for setcap()
  20. *
  21. * @return 0 if this is the child, pid of the child
  22. * if this is the parent, or -1 on error.
  23. */
  24. public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
  25. int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
  26. preFork();
  27. int pid = nativeForkSystemServer(
  28. uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
  29. postFork();
  30. return pid;
  31. }
  32. native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
  33. int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

nativeForkSystemServer最终通过JNI实现,代码为:

@/dalvik/vm/native/dalvik_system_Zygote.cpp

  1. /*
  2. * native public static int nativeForkSystemServer(int uid, int gid,
  3. *     int[] gids, int debugFlags, int[][] rlimits,
  4. *     long permittedCapabilities, long effectiveCapabilities);
  5. */
  6. static void Dalvik_dalvik_system_Zygote_forkSystemServer(
  7. const u4* args, JValue* pResult)
  8. {
  9. pid_t pid;
  10. pid = forkAndSpecializeCommon(args, true);
  11. /* The zygote process checks whether the child process has died or not. */
  12. if (pid > 0) {//pid大于0,说明是在父进程中
  13. int status;
  14. ALOGI("System server process %d has been created", pid);
  15. gDvm.systemServerPid = pid;
  16. /* There is a slight window that the system server process has crashed
  17. * but it went unnoticed because we haven't published its pid yet. So
  18. * we recheck here just to make sure that all is well.
  19. */
  20. if (waitpid(pid, &status, WNOHANG) == pid) {//堵塞,等待system_server进程
  21. ALOGE("System server process %d has died. Restarting Zygote!", pid);
  22. kill(getpid(), SIGKILL);//一旦上面的等待返回,说明进程pid(system_server)已终止,此时Zygote杀死自己
  23. }
  24. }
  25. RETURN_INT(pid);
  26. }

可以看出Dalvik_dalvik_system_Zygote_forkSystemServer会调用forkAndSpecializeCommon来fork出system_server进程。这里要注意最后几句,在fork出system_server以后,Zygote会调用waitpid等待system_server的终止,一旦发现system_server终止,Zygote则马上自杀。



接下来看一下handleSystemServerProcess的实现:

@/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

  1. /**
  2. * Finish remaining work for the newly forked system server process.
  3. */
  4. private static void handleSystemServerProcess(
  5. ZygoteConnection.Arguments parsedArgs)
  6. throws ZygoteInit.MethodAndArgsCaller {
  7. closeServerSocket();//关闭从Zygote复制过来的socket
  8. // set umask to 0077 so new files and directories will default to owner-only permissions.
  9. Libcore.os.umask(S_IRWXG | S_IRWXO);//设置文件的默认权限,去除所有者之外的权限
  10. if (parsedArgs.niceName != null) {
  11. Process.setArgV0(parsedArgs.niceName);//system_server
  12. }
  13. if (parsedArgs.invokeWith != null) {
  14. WrapperInit.execApplication(parsedArgs.invokeWith,
  15. parsedArgs.niceName, parsedArgs.targetSdkVersion,
  16. null, parsedArgs.remainingArgs);
  17. } else {
  18. /*
  19. * Pass the remaining arguments to SystemServer.
  20. */
  21. RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
  22. }
  23. /* should never reach here */
  24. }

上面的代码中用到了Linux中的umask这个函数,不明白的读者可以参考:http://hi.baidu.com/fengyun409/item/82cd158ffe7f67c8b17154e7

下面继续看RuntimeInit.zygoteInit方法的实现:

@/frameworks/base/core/java/com/android/internel/os/RuntimeInit.java

  1. /**
  2. * The main function called when started through the zygote process. This
  3. * could be unified with main(), if the native code in nativeFinishInit()
  4. * were rationalized with Zygote startup.<p>
  5. *
  6. * Current recognized args:
  7. * <ul>
  8. *   <li> <code> [--] <start class name>  <args>
  9. * </ul>
  10. *
  11. * @param targetSdkVersion target SDK version
  12. * @param argv arg strings
  13. */
  14. public static final void zygoteInit(int targetSdkVersion, String[] argv)
  15. throws ZygoteInit.MethodAndArgsCaller {
  16. if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
  17. redirectLogStreams();//将System.out 和 System.err 输出重定向到Android 的Log系统
  18. /*
  19. * 初始化了一些系统属性,其中最重要的一点就是设置了一个未捕捉异常的handler,
  20. * 当代码有任何未知异常,就会执行它,
  21. * 调试过Android代码的同学经常看到的"*** FATAL EXCEPTION IN SYSTEM PROCESS" 打印就出自这里
  22. */
  23. commonInit();
  24. /*
  25. * 最终会调用app_main的onZygoteInit函数
  26. * 这里的作用是在新进程中引入Binder,也就说通过nativeZygoteInit以后,新的进程就可以使用Binder进程通信了
  27. */
  28. nativeZygoteInit();
  29. applicationInit(targetSdkVersion, argv);//应用初始化
  30. }

这个函数是不是有些面熟?没错在《Zygote进程【2】——Zygote的分裂》一文中我们见过,Zygote进程在接收到ActivityManagerService请求创建进程的请求时就调用的该方法来处理创建子进程的后续工作。

  1. private static void applicationInit(int targetSdkVersion, String[] argv)
  2. throws ZygoteInit.MethodAndArgsCaller {
  3. // If the application calls System.exit(), terminate the process
  4. // immediately without running any shutdown hooks.  It is not possible to
  5. // shutdown an Android application gracefully.  Among other things, the
  6. // Android runtime shutdown hooks close the Binder driver, which can cause
  7. // leftover running threads to crash before the process actually exits.
  8. nativeSetExitWithoutCleanup(true);
  9. // We want to be fairly aggressive about heap utilization, to avoid
  10. // holding on to a lot of memory that isn't needed.
  11. VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
  12. VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
  13. final Arguments args;
  14. try {
  15. args = new Arguments(argv);
  16. } catch (IllegalArgumentException ex) {
  17. Slog.e(TAG, ex.getMessage());
  18. // let the process exit
  19. return;
  20. }
  21. // Remaining arguments are passed to the start class's static main
  22. invokeStaticMain(args.startClass, args.startArgs);
  23. }

所以,这里与Zygote分裂时不同的是:这里的args.startClass的值为com.android.server.SystemServer。接下来大家都知道了,SystemServer类的main函数将会被调用。

@/frameworks/base/services/java/com/android/server/SystemServer.java

  1. public static void main(String[] args) {
  2. if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
  3. // If a device's clock is before 1970 (before 0), a lot of
  4. // APIs crash dealing with negative numbers, notably
  5. // java.io.File#setLastModified, so instead we fake it and
  6. // hope that time from cell towers or NTP fixes it
  7. // shortly.
  8. Slog.w(TAG, "System clock is before 1970; setting to 1970.");
  9. SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);//初始化系统时间
  10. }
  11. if (SamplingProfilerIntegration.isEnabled()) {
  12. SamplingProfilerIntegration.start();
  13. timer = new Timer();
  14. timer.schedule(new TimerTask() {
  15. @Override
  16. public void run() {
  17. SamplingProfilerIntegration.writeSnapshot("system_server", null);
  18. }
  19. }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
  20. }
  21. // Mmmmmm... more memory!
  22. dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
  23. // The system server has to run all of the time, so it needs to be
  24. // as efficient as possible with its memory usage.
  25. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
  26. Environment.setUserRequired(true);
  27. System.loadLibrary("android_servers");//加载android_servers库
  28. Slog.i(TAG, "Entered the Android system server!");
  29. // Initialize native services.
  30. nativeInit();//初始化native service
  31. // This used to be its own separate thread, but now it is
  32. // just the loop we run on the main thread.
  33. ServerThread thr = new ServerThread();
  34. thr.initAndLoop();
  35. }

在main中会加载libandroid_servers.so库,然后调用nativeInit初始化native层的Service。

  1. /**
  2. * Called to initialize native system services.
  3. */
  4. private static native void nativeInit();

@/frameworks/base/services/jni/com_android_server_SystemServer.cpp

  1. static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
  2. char propBuf[PROPERTY_VALUE_MAX];
  3. property_get("system_init.startsensorservice", propBuf, "1");
  4. if (strcmp(propBuf, "1") == 0) {
  5. // Start the sensor service
  6. SensorService::instantiate();
  7. }
  8. }

可以看出这里只初始化了传感器service,这与之前的代码有所不同,在比较早的Android版本中,服务的初始化分为init1和init2两个过程,其中init主要负责native层service的初始化(SurfaceFlinger、AudioFlinger等),init2负责java层service的初始化。

在main方法最后会调用ServerThread类的initAndLoop来初始化系统服务,这个函数比较长,这里就不复制代码了。

好了,到这里SystemServer的诞生过程就完了

Zygote进程【3】——SystemServer的诞生的更多相关文章

  1. Zygote进程介绍【转】

    本文转载自:http://blog.csdn.net/yangwen123/article/details/17258023 Zygote进程介绍   在Android系统中,存在不同的服务,这些服务 ...

  2. Zygote进程【1】——Zygote的诞生

    在Android中存在着C和Java两个完全不同的世界,前者直接建立在Linux的基础上,后者直接建立在JVM的基础上.zygote的中文名字为"受精卵",这个名字很好的诠释了zy ...

  3. Zygote进程【2】——Zygote的分裂

    在Zygote的诞生一文中init进程是如何一步步创建Zygote进程的,也了解了Zygote的进程的作用.Zygote进程的诞生对于整个Java世界可以说有着"开天辟地"的作用, ...

  4. Android4.4 Framework分析——Zygote进程的启动过程

    Android启动过程中的第一个进程init.在启动过程中会启动两个关键的系统服务进程ServiceManager和Zygote. 本文要介绍的就是Zygote进程的启动,Zygote俗称孵化器,专门 ...

  5. Android系统启动流程(二)解析Zygote进程启动过程

    1.Zygote简介 在Android系统中,DVM(Dalvik虚拟机).应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器.它通过 ...

  6. Android4.4的zygote进程(下)

    3.2.4启动Android系统服务——startSystemServer() 接下来就是启动Android的重头戏了,此时ZygoteInit的main()函数会调用startSystemServe ...

  7. Android Zygote进程启动分析

    dvm,app进程,linux进程三者关系 DVM指 dalivk 的虚拟机.每一个 Android 应用程序都在它自己的进程中运行,都拥有一个独立的 Dalvik 虚拟机实例.而每一个 DVM 都是 ...

  8. Android4.4的zygote进程(上)

    1背景 前些天为了在科室做培训,我基于Android 4.4重新整理了一份关于zygote的文档.从技术的角度看,这几年zygote并没有出现什么大的变化,所以如果有人以前研究过zygote,应该不会 ...

  9. Android Zygote进程是如何fork一个APP进程的

    进程创建流程 不管从桌面启动应用还是应用内启动其它应用,如果这个应用所在进程不存在的话,都需要发起进程通过Binder机制告诉system server进程的AMS system server进程的A ...

随机推荐

  1. 【转】SharePoint camel query查询 event 或者Calendar 日历列表的时候,怎么查询所有的重复发生的事件

    When you query a SharePoint calendar your results will contain: All non-recurring events The first e ...

  2. [ javascript canvas 插件演示 ] canvas 插件演示

    <!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title ...

  3. DevExpress VCL 13.1.4支持Delphi /C++Builder XE5

    DevExpress VCL 13.1.4支持Delphi /C++Builder XE5 重大变化 ExpressLibrary dxHalfOfPi常数声明已经从cxGeometry单元移到了cx ...

  4. Android 动态创建Fragment

    Fragment是activity的界面中的一部分或一种行为.可以把多个Fragment组合到一个activity中来创建一个多界面并且可以在多个activity中重用一个Fragment.可以把Fr ...

  5. OC中的面向对象语法

    一. 面向对象和面向过程思想 OC是面向对象的,C是面向过程的.面向对象和面向过程只是解决问题的两种不同思想 1. 面向对象和面向过程的区别 1) 以用电脑听歌为例子 a) 面向过程 打开电脑 播放电 ...

  6. C++语言-05-三大特性

    概述 C++ 是面向对象的语言,具备 OOP 的基本特性. 封装 概念 将数据和操作数据的函数绑定在一起 作用 避免受到外界的干扰和误用,确保了安全 与封装相关的概念 数据抽象 仅向用户暴露接口而把具 ...

  7. js document.createElement()的用法 (转)

    document.createElement()的用法 分析代码时,发现自己的盲点--document.createElement(),冲浪一番,总结了点经验. document.createElem ...

  8. .NET/ASP.NET 4.5 Bundle组件(捆绑、缩小静态文件)

    阅读目录: 1.开篇介绍 2.System.Web.Optimization 组件 3.System.Web.Optimization 组件基本原理 4.扩展自定义类型静态文件 1]开篇介绍 这篇文章 ...

  9. js相对路径相关(比如:js中的路径依赖导入该js文件的路径)

    问题描述: 前几天调用同事的js接口文件,在他自己的html测试页面ok,在我这边调用时出现问题. debug过程中,将该测试html移到其他位置都不行,放到原html测试页面同层次路径下是OK的. ...

  10. 导出HTML

    版权声明:本文为博主原创文章,未经博主允许不得转载.