欢迎转载。转载请注明: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诞生的更多相关文章

  1. IT兄弟连 HTML5教程 HTML5的曲折发展过程 HTML5的诞生

    十年磨一剑,正如我们所看到的一样,HTML5大潮正来势汹汹.但也正如我们所知道的一样,HTML5是一种技术标准,它的语义之美.人性之美.简单之美.实用之美……如同一场革命,它的主要应用场景是浏览器,不 ...

  2. [深入理解Android卷一全文-第四章]深入理解zygote

    由于<深入理解Android 卷一>和<深入理解Android卷二>不再出版,而知识的传播不应该由于纸质媒介的问题而中断,所以我将在CSDN博客中全文转发这两本书的所有内容. ...

  3. Zygote浅谈

    Zygote是什么 操作系统中,进程实际上是文件到地址空间的映射像.进程将要运行时,由操作系统将其映射到地址空间,完成这项工作的事物本质也应是一个进程,我们称这个进程为孵化进程,那么这个进程怎么收到消 ...

  4. Android 内核初识(6)SystemServer进程

    简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...

  5. Android(java)学习笔记161:Framework运行环境之启动SystemServer进程

          SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServer()开始的.与启动普通进程的差别 ...

  6. 【转】Android 内核初识(6)SystemServer进程

    简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...

  7. Android Zygote进程启动分析

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

  8. Android(java)学习笔记104:Framework运行环境之启动SystemServer进程

    1. SystemServer进程      SystemServer进程是zygote孵化出的第一个进程,该进程是从ZygoteInit.java的main函数中调用startSystemServe ...

  9. Zygote进程介绍【转】

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

随机推荐

  1. NET之全平台一体化

    NET之全平台一体化的体验 一.前言 近来利用空闲时间研究了一下Xamarin的技术,想想既然提供了如此好的支持,就该尝试一切可能,来一个”大小通吃“. 何为全平台:APP包括Android.IOS. ...

  2. uva 1434 - YAPTCHA(数论)

    题目链接:uva 1434 - YAPTCHA 题目大意:给定n和k,求题目中给定的式子S(n). 解题思路:威尔逊定理,x为素数时有,((x−1)!+1)%x==0,所以对于本题.假设3*k+7为素 ...

  3. 2014 CSDN博文大赛终于获奖名单发布

    博文大赛第二阶段(2014年7月15日-2014年8月10日)已经结束,决赛获奖名单已在8月11日出炉. 现将获奖名单发布: 移动开发 NO.1    罗升阳    Luoshengyang    S ...

  4. liunx清理磁盘du -h --max-depth=1 /data/*

    liunx清理磁盘du -h --max-depth=1 /data/*

  5. Cocos2d-x教程(28)-ttf 字体库的使用

    欢迎增加 Cocos2d-x 交流群: 193411763 转载请注明原文出处:http://blog.csdn.net/u012945598/article/details/37650843 通常为 ...

  6. 通过Java反射调用方法

    这是个测试用的例子,通过反射调用对象的方法.     TestRef.java import java.lang.reflect.Method; import java.lang.reflect.In ...

  7. WPF界面设计技巧(1)—不规则窗体图文指南

    原文:WPF界面设计技巧(1)-不规则窗体图文指南 初到园子,奉上第一篇入门级教程,请勿见笑. 以往WinForm编程中,实现不规则窗体是有一定难度的,更难的是不规则窗体的边缘抗锯齿及局部透明处理.而 ...

  8. 蓝缘管理系统第二个版本号开源了。springMVC+springSecurity3.x+Mybaits3.x 系统

    蓝缘管理系统第二个版本号开源了 继于 http://blog.csdn.net/mmm333zzz/article/details/16863543 版本号一.版本号二 对springMVC+spri ...

  9. FusionCharts參数中文说明

    FushionCharts是把抽象数据图示化的套件,使用方便,配置简单.其相关參数中文说明例如以下. 功能特性 animation                    是否动画显示数据,默觉得 1( ...

  10. POJ3190 Stall Reservations 【贪婪】

    Stall Reservations Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3106   Accepted: 111 ...