Zygote过程【3】——SystemServer诞生

Zygote过程【3】——SystemServer诞生

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

欢迎转载。转载请注明: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的诞生过程就完了

版权声明:本文博客原创文章。博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/117654.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • phpstrom激活码2021_通用破解码

    phpstrom激活码2021_通用破解码,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • 探秘X86架构CPU流水线[通俗易懂]

    探秘X86架构CPU流水线[通俗易懂]http://ee.ofweek.com/2013-07/ART-11001-2805-28704745.html导读:CPU是如何工作的呢?一条指令执行需要多长时间?当我们讨论某个新款处理器拥有12级流水线还是18级流水线,甚至是更深的31级流水线时,这到些都意味着什么呢?作为程序员,CPU在我们的工作中扮演了核心角色,因此了解处理器内部的工作方式对程序员来说不无裨益。  CPU…

  • 以太网用户侧接口(以太网协议转换方案)

    以太网接口示意图如下图1:以太网接口 如果您的职业生涯大部分时间都在从事PCB设计,并且您在计算机接口的布局和布线方面有经验,那么您就知道一件事是正确的:在器件应用说明中会有一些推荐的设计建议,并不是这些建议总是错误的,而是这些建议很容易断章取义。一位同事向我提出的一项建议是,在离散磁铁和连接器之间布线时,在RJ45连接器下方使用接地层。一些应用说明建议将系统接地覆盖RJ45连接器下方,一些应用说明建议将接地平面拆分为系统和机箱部分,以提供更强的隔离。应用说明中的一些建议指出,PHY、磁体和/或

  • keypad 按键响应流程解析「建议收藏」

    keypad 按键响应流程解析「建议收藏」一、keypad驱动,接收按键事件并将按键值转换为Linuxcode上发。二、如何一层层上传到Android系统的控件中。

  • CSS样式表定义

    CSS样式表定义一个JSP页面是通过在HTML标签的基础上嵌入JSP动作和指令、CSS、Java变量和方法(Java代码段)、其他脚本元素(如JavaScript)等组成的。

  • pycharm 字体设置「建议收藏」

    pycharm 字体设置「建议收藏」pycharm字体设置

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号