Zygote过程【3】——SystemServer诞生
欢迎转载。转载请注明:http://blog.csdn.net/zhgxhuaa
在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诞生的更多相关文章
- IT兄弟连 HTML5教程 HTML5的曲折发展过程 HTML5的诞生
十年磨一剑,正如我们所看到的一样,HTML5大潮正来势汹汹.但也正如我们所知道的一样,HTML5是一种技术标准,它的语义之美.人性之美.简单之美.实用之美……如同一场革命,它的主要应用场景是浏览器,不 ...
- [深入理解Android卷一全文-第四章]深入理解zygote
由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的所有内容. ...
- Zygote浅谈
Zygote是什么 操作系统中,进程实际上是文件到地址空间的映射像.进程将要运行时,由操作系统将其映射到地址空间,完成这项工作的事物本质也应是一个进程,我们称这个进程为孵化进程,那么这个进程怎么收到消 ...
- Android 内核初识(6)SystemServer进程
简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...
- Android(java)学习笔记161:Framework运行环境之启动SystemServer进程
SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServer()开始的.与启动普通进程的差别 ...
- 【转】Android 内核初识(6)SystemServer进程
简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...
- Android Zygote进程启动分析
dvm,app进程,linux进程三者关系 DVM指 dalivk 的虚拟机.每一个 Android 应用程序都在它自己的进程中运行,都拥有一个独立的 Dalvik 虚拟机实例.而每一个 DVM 都是 ...
- Android(java)学习笔记104:Framework运行环境之启动SystemServer进程
1. SystemServer进程 SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServe ...
- Zygote进程介绍【转】
本文转载自:http://blog.csdn.net/yangwen123/article/details/17258023 Zygote进程介绍 在Android系统中,存在不同的服务,这些服务 ...
随机推荐
- UDP vs. TCP
UDP vs. TCP 原文:UDP vs. TCP,作者是Glenn Fiedler,专注于游戏网络编程相关工作多年. 说在最前面的话 翻译这篇文章的初衷:我在工作中根本接触不到网络游戏编程,但是我 ...
- phpc.sinaapp.com 加密的解密方法
原文:phpc.sinaapp.com 加密的解密方法 很简单,用类似phpjm的解密方式,替换掉_inc.php中最后一个return中的eval为print就出来了.
- [Xcode]使用target进行协同开发
协同开发时候发现难免会因为某些条件宏导致上传到SVN的代码影响到其他同时,但是每一次去修很多条件编译也不是很方便,所以可以通过新建自己的target来控制product. 一.创建自己的target: ...
- CoreJava_Collection接口add有一个返回值!
今天讨论与朋友小知识,我发现很多人不知道collection接口定义add方法返回的值,我们所有的工作很多年Java职工.不熟悉的公共接口,使自己成为在细节上的麻烦.一个小采访这让我想起,当我 ...
- VSTO学习笔记(九)浅谈Excel内容比较
原文:VSTO学习笔记(九)浅谈Excel内容比较 说起文件内容比较,或许我们首先想到的是UltraCompare这类专业比较的软件,其功能非常强大,能够对基于文本的文件内容作出快速.准确的比较,有详 ...
- JAVA Socket(多个客户同时连接,信息共享) client (java/ruby)
第一步 充分理解Socket 1.什么是socket 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字" ...
- KISSY 库 demo
KISSY 是由淘宝前端project师们发起创建的一个开源 JS 类库. 它遵循的原则是 小巧灵活.简洁有用.愉悦编码.快乐开发. DEMO: <!DOCTYPE html> <h ...
- SWT的TableVierer的使用二(数据排序)
有一个功能是我们常使用的,就是在列的头上点击一下,整个表的记录按照这个列来排序,再点击一下按照这个列的反序来排序.那JFace是如何实现这个功能的呢?在JFace中是通过一个排序器来实现的,就是Vie ...
- C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象
重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt { int operator() (int v ...
- Nagios+pnp4nagios+rrdtool 安装配置为nagios添加自定义插件(三)
nagios博大精深,可以以shell.perl等语句为nagios写插件,来满足自己监控的需要.本文写mysql中tps.qps的插件,并把收集到的结果以图形形式展现出来,这样输出的结果就有一定的要 ...