Zygote进程【3】——SystemServer的诞生
在ZygoteInit的main()方法中做了几件大事,其中一件便是启动Systemserver进程,代码如下:
@/frameworks/base/core/Java/com/Android/internal/os/ZygoteInit.java
- public static void main(String argv[]) {
- try {
- ......
- if (argv[1].equals("start-system-server")) {
- startSystemServer();//启动system_server进程
- } else if (!argv[1].equals("")) {
- throw new RuntimeException(argv[0] + USAGE_STRING);
- }
- ......
- }
startSystemServer方法的实现如下:
@/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
- /**
- * Prepare the arguments and fork for the system server process.
- */
- private static boolean startSystemServer()
- throws MethodAndArgsCaller, RuntimeException {
- long capabilities = posixCapabilitiesAsBits(
- 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,1032,3001,3002,3003,3006,3007",
- "--capabilities=" + capabilities + "," + capabilities,
- "--runtime-init",
- "--nice-name=system_server",
- "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(//以fork的方式创建system_server进程
- 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) {//pid==0说明在子进程中,父进程为Zygote
- handleSystemServerProcess(parsedArgs);
- }
- return true;
- }
在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
- /**
- * Special method to start the system server process. In addition to the
- * common actions performed in forkAndSpecialize, the pid of the child
- * process is recorded such that the death of the child process will cause
- * zygote to exit.
- *
- * @param uid the UNIX uid that the new process should setuid() to after
- * fork()ing and and before spawning any threads.
- * @param gid the UNIX gid that the new process should setgid() to after
- * fork()ing and and before spawning any threads.
- * @param gids null-ok; a list of UNIX gids that the new process should
- * setgroups() to after fork and before spawning any threads.
- * @param debugFlags bit flags that enable debugging features.
- * @param rlimits null-ok an array of rlimit tuples, with the second
- * dimension having a length of 3 and representing
- * (resource, rlim_cur, rlim_max). These are set via the posix
- * setrlimit(2) call.
- * @param permittedCapabilities argument for setcap()
- * @param effectiveCapabilities argument for setcap()
- *
- * @return 0 if this is the child, pid of the child
- * if this is the parent, or -1 on error.
- */
- public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
- preFork();
- int pid = nativeForkSystemServer(
- uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
- postFork();
- return pid;
- }
- native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
nativeForkSystemServer最终通过JNI实现,代码为:
@/dalvik/vm/native/dalvik_system_Zygote.cpp
- /*
- * native public static int nativeForkSystemServer(int uid, int gid,
- * int[] gids, int debugFlags, int[][] rlimits,
- * long permittedCapabilities, long effectiveCapabilities);
- */
- static void Dalvik_dalvik_system_Zygote_forkSystemServer(
- const u4* args, JValue* pResult)
- {
- pid_t pid;
- pid = forkAndSpecializeCommon(args, true);
- /* The zygote process checks whether the child process has died or not. */
- if (pid > 0) {//pid大于0,说明是在父进程中
- int status;
- ALOGI("System server process %d has been created", pid);
- gDvm.systemServerPid = pid;
- /* There is a slight window that the system server process has crashed
- * but it went unnoticed because we haven't published its pid yet. So
- * we recheck here just to make sure that all is well.
- */
- if (waitpid(pid, &status, WNOHANG) == pid) {//堵塞,等待system_server进程
- ALOGE("System server process %d has died. Restarting Zygote!", pid);
- kill(getpid(), SIGKILL);//一旦上面的等待返回,说明进程pid(system_server)已终止,此时Zygote杀死自己
- }
- }
- RETURN_INT(pid);
- }
可以看出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
- /**
- * Finish remaining work for the newly forked system server process.
- */
- private static void handleSystemServerProcess(
- ZygoteConnection.Arguments parsedArgs)
- throws ZygoteInit.MethodAndArgsCaller {
- closeServerSocket();//关闭从Zygote复制过来的socket
- // set umask to 0077 so new files and directories will default to owner-only permissions.
- Libcore.os.umask(S_IRWXG | S_IRWXO);//设置文件的默认权限,去除所有者之外的权限
- if (parsedArgs.niceName != null) {
- Process.setArgV0(parsedArgs.niceName);//system_server
- }
- if (parsedArgs.invokeWith != null) {
- WrapperInit.execApplication(parsedArgs.invokeWith,
- parsedArgs.niceName, parsedArgs.targetSdkVersion,
- null, parsedArgs.remainingArgs);
- } else {
- /*
- * Pass the remaining arguments to SystemServer.
- */
- RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
- }
- /* should never reach here */
- }
上面的代码中用到了Linux中的umask这个函数,不明白的读者可以参考:http://hi.baidu.com/fengyun409/item/82cd158ffe7f67c8b17154e7。
下面继续看RuntimeInit.zygoteInit方法的实现:
@/frameworks/base/core/java/com/android/internel/os/RuntimeInit.java
- /**
- * The main function called when started through the zygote process. This
- * could be unified with main(), if the native code in nativeFinishInit()
- * were rationalized with Zygote startup.<p>
- *
- * Current recognized args:
- * <ul>
- * <li> <code> [--] <start class name> <args>
- * </ul>
- *
- * @param targetSdkVersion target SDK version
- * @param argv arg strings
- */
- public static final void zygoteInit(int targetSdkVersion, String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
- if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
- redirectLogStreams();//将System.out 和 System.err 输出重定向到Android 的Log系统
- /*
- * 初始化了一些系统属性,其中最重要的一点就是设置了一个未捕捉异常的handler,
- * 当代码有任何未知异常,就会执行它,
- * 调试过Android代码的同学经常看到的"*** FATAL EXCEPTION IN SYSTEM PROCESS" 打印就出自这里
- */
- commonInit();
- /*
- * 最终会调用app_main的onZygoteInit函数
- * 这里的作用是在新进程中引入Binder,也就说通过nativeZygoteInit以后,新的进程就可以使用Binder进程通信了
- */
- nativeZygoteInit();
- applicationInit(targetSdkVersion, argv);//应用初始化
- }
这个函数是不是有些面熟?没错在《Zygote进程【2】——Zygote的分裂》一文中我们见过,Zygote进程在接收到ActivityManagerService请求创建进程的请求时就调用的该方法来处理创建子进程的后续工作。
- private static void applicationInit(int targetSdkVersion, String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
- // If the application calls System.exit(), terminate the process
- // immediately without running any shutdown hooks. It is not possible to
- // shutdown an Android application gracefully. Among other things, the
- // Android runtime shutdown hooks close the Binder driver, which can cause
- // leftover running threads to crash before the process actually exits.
- nativeSetExitWithoutCleanup(true);
- // We want to be fairly aggressive about heap utilization, to avoid
- // holding on to a lot of memory that isn't needed.
- VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
- VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
- final Arguments args;
- try {
- args = new Arguments(argv);
- } catch (IllegalArgumentException ex) {
- Slog.e(TAG, ex.getMessage());
- // let the process exit
- return;
- }
- // Remaining arguments are passed to the start class's static main
- invokeStaticMain(args.startClass, args.startArgs);
- }
所以,这里与Zygote分裂时不同的是:这里的args.startClass的值为com.android.server.SystemServer。接下来大家都知道了,SystemServer类的main函数将会被调用。
@/frameworks/base/services/java/com/android/server/SystemServer.java
- public static void main(String[] args) {
- if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
- // If a device's clock is before 1970 (before 0), a lot of
- // APIs crash dealing with negative numbers, notably
- // java.io.File#setLastModified, so instead we fake it and
- // hope that time from cell towers or NTP fixes it
- // shortly.
- Slog.w(TAG, "System clock is before 1970; setting to 1970.");
- SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);//初始化系统时间
- }
- if (SamplingProfilerIntegration.isEnabled()) {
- SamplingProfilerIntegration.start();
- timer = new Timer();
- timer.schedule(new TimerTask() {
- @Override
- public void run() {
- SamplingProfilerIntegration.writeSnapshot("system_server", null);
- }
- }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
- }
- // Mmmmmm... more memory!
- dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
- // The system server has to run all of the time, so it needs to be
- // as efficient as possible with its memory usage.
- VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
- Environment.setUserRequired(true);
- System.loadLibrary("android_servers");//加载android_servers库
- Slog.i(TAG, "Entered the Android system server!");
- // Initialize native services.
- nativeInit();//初始化native service
- // This used to be its own separate thread, but now it is
- // just the loop we run on the main thread.
- ServerThread thr = new ServerThread();
- thr.initAndLoop();
- }
在main中会加载libandroid_servers.so库,然后调用nativeInit初始化native层的Service。
- /**
- * Called to initialize native system services.
- */
- private static native void nativeInit();
@/frameworks/base/services/jni/com_android_server_SystemServer.cpp
- static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
- char propBuf[PROPERTY_VALUE_MAX];
- property_get("system_init.startsensorservice", propBuf, "1");
- if (strcmp(propBuf, "1") == 0) {
- // Start the sensor service
- SensorService::instantiate();
- }
- }
可以看出这里只初始化了传感器service,这与之前的代码有所不同,在比较早的Android版本中,服务的初始化分为init1和init2两个过程,其中init主要负责native层service的初始化(SurfaceFlinger、AudioFlinger等),init2负责java层service的初始化。
在main方法最后会调用ServerThread类的initAndLoop来初始化系统服务,这个函数比较长,这里就不复制代码了。
好了,到这里SystemServer的诞生过程就完了
Zygote进程【3】——SystemServer的诞生的更多相关文章
- Zygote进程介绍【转】
本文转载自:http://blog.csdn.net/yangwen123/article/details/17258023 Zygote进程介绍 在Android系统中,存在不同的服务,这些服务 ...
- Zygote进程【1】——Zygote的诞生
在Android中存在着C和Java两个完全不同的世界,前者直接建立在Linux的基础上,后者直接建立在JVM的基础上.zygote的中文名字为"受精卵",这个名字很好的诠释了zy ...
- Zygote进程【2】——Zygote的分裂
在Zygote的诞生一文中init进程是如何一步步创建Zygote进程的,也了解了Zygote的进程的作用.Zygote进程的诞生对于整个Java世界可以说有着"开天辟地"的作用, ...
- Android4.4 Framework分析——Zygote进程的启动过程
Android启动过程中的第一个进程init.在启动过程中会启动两个关键的系统服务进程ServiceManager和Zygote. 本文要介绍的就是Zygote进程的启动,Zygote俗称孵化器,专门 ...
- Android系统启动流程(二)解析Zygote进程启动过程
1.Zygote简介 在Android系统中,DVM(Dalvik虚拟机).应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器.它通过 ...
- Android4.4的zygote进程(下)
3.2.4启动Android系统服务——startSystemServer() 接下来就是启动Android的重头戏了,此时ZygoteInit的main()函数会调用startSystemServe ...
- Android Zygote进程启动分析
dvm,app进程,linux进程三者关系 DVM指 dalivk 的虚拟机.每一个 Android 应用程序都在它自己的进程中运行,都拥有一个独立的 Dalvik 虚拟机实例.而每一个 DVM 都是 ...
- Android4.4的zygote进程(上)
1背景 前些天为了在科室做培训,我基于Android 4.4重新整理了一份关于zygote的文档.从技术的角度看,这几年zygote并没有出现什么大的变化,所以如果有人以前研究过zygote,应该不会 ...
- Android Zygote进程是如何fork一个APP进程的
进程创建流程 不管从桌面启动应用还是应用内启动其它应用,如果这个应用所在进程不存在的话,都需要发起进程通过Binder机制告诉system server进程的AMS system server进程的A ...
随机推荐
- SharePoint 2013 搜索报错"Unable to retrieve topology component health. This may be because the admin component is not up and running"
环境描述 Windows 2012 R2,SharePoint 2013(没有sp1补丁),sql server 2012 错误描述 搜索服务正常,但是爬网一直在Crawling Full,但是爬不到 ...
- Sharepoint学习笔记—习题系列--70-576习题解析 -(Q78-Q80)
Question 78 You are designing an application configuration approach for a custom SharePoint 2010 app ...
- Android 图片的平移和镜面和倒影效果
在前面的文章中陆续介绍了图片的旋转与缩放,本文继续介绍关于图片的操作 图片的平移 使用下面的代码将图水平竖直方向平移10个像素 matrix.setTranslate(10, 10); 可以看到图片不 ...
- Android 使用xml序列化器生成xml文件
在<Android 生成xml文件>一文中使用流的形式写入xml格式文件,但是存在一定的问题,那就是在短信内容中不能出现<>之类的括号,本文使用xml序列化器来解决 xml序列 ...
- Swift 初步了解
Swift 初步了解 前言: 本篇博客会结合OC对Swift进行简单介绍. OC 用NSLog输出日志 NSLog(@"旭宝爱吃鱼"); Swift 用print输出日志 prin ...
- Fragment与Activity之间的通信
我个人将Fragment与Activity间的通信比喻为JSP与Servlet间的通信,fragment中用接口的方式来进行与Activity的通信.通信的结果可以作为数据传入另一个Fragmen ...
- 初次使用 git 的“核弹级选项”:filter-branch 从仓库中删除文件
当初看 Pro Git 时就被作者这个“核弹级选项”的称呼吓到了,因此一直没敢好奇地去尝试.核弹啊,用对了威力无穷,用错了破坏力无穷! 但是,今天,我不得不用了,因为我想把我的原来写一些代码放到 gi ...
- Java中的基本数据类型
什么是基本数据类型 就是我们在编程的时候经常需要用到的数据类型,如整型,浮点型等,把这些数据类型专门拿出来特殊对待,并想象成所谓的“基本类型”. Java中有哪些基本数据类型
- jmeter 性能测试工具的使用(Web性能测试)
1.下载 http://pan.baidu.com/s/1o7p18Ye 该软件不用安装,直接解压打开即可使用. 2.使用 这里就在win下进行,图形界面较为方便 在目录apache-jmeter-2 ...
- RAM,SRAM,DRAM,SDRAM,DDR RAM,ROM,PROM,EPROM,EEPROM,NAND FLASH,NOR FLASH的区别
RAM:由字面意思就可以理解,SDRAM SRAM DRAM(下面蓝色字体的这几种)都可以统称RAM,random access memory(随机存取存储器)的缩写,下面是51hei.com为大家整 ...