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 showModalDialog 弹出模式窗口
1. SharePoint 弹出框 本文讲述SharePoint 2013 中使用 SP.UI.ModalDialog.showModalDialog时 showModalDialog 未定义的问题 ...
- 获取设备的mac地址可靠的方法
参考自:http://www.open-open.com/lib/view/open1433406847322.html /** * 获取设备的mac地址 * * @param ac * @param ...
- 表达式语言EL
表达式语言EL 表达式语言 EL(Expression Language,表达式语言)主要是用在JSP页面中,用来辅助我们产生无脚本的JSP页面,此处的脚本指的是JSP中的Java代码. EL的语法是 ...
- unbuntu apahce 2 设置 多域名
1.找到apache2 的设置路径 默认的apache的路径为/etc/apache2/ 2. 修改httpd.conf 本文192.168.0.1 为自己的服务器的ip,下面一样的意思 Server ...
- sqlite之WAL模式
链接 概述 在3.7.0以后,WAL(Write-Ahead Log)模式可以使用,是另一种实现事务原子性的方法. WAL的优点 在大多数情况下更快 并行性更高.因为读操作和写操作可以并行. 文件IO ...
- sshd安装
centos yum install openssh-server #chkconfig --level 2345 sshd on #service sshd restart 重新启动 #netsta ...
- ASP.NET处理301重定向方法 带示例 (demo)
System.Web.HttpContext.Current.Response.Status = "301 Moved Permanently"; System.Web.HttpC ...
- mvc 开发razor模式注意事项
1 情景为:mvc模式开发的.cshtml画面,里面有@if语句,if语句里面还有其他的代码,画面总是报错:if模块中没有对应的"}",什么问题 跟踪了之后,判定cs语句没问题,那 ...
- mysql-5 数据检索(3)
计算字段 如果想在一个字段中既显示公司的名称,又显示公司的地址,但是这两个信息一般包含在不同的表列中 城市.州和邮政编码存储在不同的列中,但是邮件标签打印程序却需要把它们作为一个恰当格式的字段检索出来 ...
- EF Power Tools 数据库逆向生成时T4模板修改
VS2013上使用EF Power Tools的Reverse Engineer Code First逆向生成. 发现数据库中的decimal(18, 4)字段在生成的mapping类中没有精度和小数 ...