`
sharp2wing
  • 浏览: 267520 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

System Server 分析

阅读更多
SystemServer 是 Android Java 层的系统服务模块,这个模块主要功能就是管理供 Android 应用开发的 system service.
一.SystemServer 类是如何启动的

让我们从 Android 的启动过程看起,查看 init.rc 文件,就会发现下面这一行service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server

我们知道 zygote 进程是整个 Android 的孵化器进程,所有的 Activity 进程均是通过它来生成的。我们发现在 zygote 进程启动过程中指定了这么一个参数“– start-system-server” ,这个参数就是在 zygote 进程启动的同时启动 SystemServer 。

那么 SystemServer 是以什么样的形式启动的呢?是单独的一个进程还是线程,分析一下 zygote 进程的启动过程就明白了。在 Android 中 zygote 进程启动其实就是启动 /system/bin/app_process 这个进程,这个进程的源代码在 frameworks/base/cmds/app_process/app_main.cpp 中。

        if (0 == strcmp("--zygote", arg)) {
            bool startSystemServer = (i < argc) ?
                    strcmp(argv[i], "--start-system-server") == 0 : false;
            setArgv0(argv0, "zygote");
            set_process_name("zygote");
            runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer);
        } else {
            set_process_name(argv0);

            runtime.mClassName = arg;

            // Remainder of args get passed to startup class main()
            runtime.mArgC = argc-i;
            runtime.mArgV = argv+i;

            LOGV("App process is starting with pid=%d, class=%s.\n",
                 getpid(), runtime.getClassName());
            runtime.start();
        }

由于 zygote 进程启动过程有“ –zygote” 这个参数,所以走的是下面这步

runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);

查看对象 runtime 的类型的定义,

class AppRuntime : public AndroidRuntime

因此查看 AndroidRuntime 的 start 方法中的一段代码 (frameworks/base/core/jni/AndroidRuntime.cpp)

    startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            LOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif

其中 startClass 即为 “com.android.internal.os.ZygoteInit” ,这段代码调用了 com.android.internal.os.ZygoteInit 的 main 函数。

那么再往下看 ZygoteInit 类的 main 函数,其中的一段 MethodAndArgsCaller 代码为

            if (argv[1].equals("true")) {
                startSystemServer();
            } else if (!argv[1].equals("false")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

调用了 startSystemServer () ,这个函数启动了一个子进程来作为 SystemServer 的载体,

1. 它首先指定 SystemServer 进程的参数 ;

2. 根据指定的参数来创建 SystemServer 进程;

3. 调用 handleSystemServerProcess 启动第一步指定进程参数过程中指定的类,此时为“ com.android.server.SystemServer ” ,启动的这个进程在 ps 查看后显示为” system_server ” 。

    private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
        /* Hardcoded command line to start the system server */
        String args[];
        String ashmem_size = System.getProperty("gralloc.ashmem_size");
        if ((null != ashmem_size) && (0 != ashmem_size.length())) {
            args = new String[] {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
                "--capabilities=130104352,130104352",
                "--rlimit=8,",
                "--runtime-init",
                "--nice-name=system_server",
                "com.android.server.SystemServer",
            };
            args[4] = args[4].concat(ashmem_size);
            args[4] = args[4].concat(",");
            args[4] = args[4].concat(ashmem_size);
        } else {
            args = new String[] {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
                "--capabilities=130104352,130104352",
                "--runtime-init",
                "--nice-name=system_server",
                "com.android.server.SystemServer",
            };
        }
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);

            /*
             * Enable debugging of the system process if *either* the command line flags
             * indicate it should be debuggable or the ro.debuggable system property
             * is set to "1"
             */
            int debugFlags = parsedArgs.debugFlags;
            if ("1".equals(SystemProperties.get("ro.debuggable")))
                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

            int[][] rlimits = new int[0][0];

            if (parsedArgs.rlimits != null) {
                rlimits = parsedArgs.rlimits.toArray(rlimits);
            }

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, rlimits,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

通过以上过程就会调用到 SystemServer 类,且是运行在一个名为“ system_server” 的进程中,这个进程为 zygote 的子进程。

虽然 SystemServer 类是运行在 system_server 中的,但是它并不运行在 system_server 的主线程中。

  /**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();

        /*
         * Pass the remaining arguments to SystemServer.
         * "--nice-name=system_server com.android.server.SystemServer"
         */
        RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
        /* should never reach here */
    }

/**
     * The main function called when started through the zygote process. This
     * could be unified with main(), if the native code in finishInit()
     * were rationalized with Zygote startup.&lt;p&gt;
     *
     */
    public static final void zygoteInit(String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        // TODO: Doing this here works, but it seems kind of arbitrary. Find
        // a better place. The goal is to set it up for applications, but not
        // tools like am.
        System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
        System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));

        commonInit();
        zygoteInitNative();

        int curArg = 0;
        for ( /* curArg */ ; curArg &lt; argv.length; curArg++) {
            String arg = argv[curArg];

            if (arg.equals("--")) {
                curArg++;
                break;
            } else if (!arg.startsWith("--")) {
                break;
            } else if (arg.startsWith("--nice-name=")) {
                String niceName = arg.substring(arg.indexOf('=') + 1);
                Process.setArgV0(niceName);
            }
        }

        if (curArg == argv.length) {
            Slog.e(TAG, "Missing classname argument to RuntimeInit!");
            // let the process exit
            return;
        }

        // Remaining arguments are passed to the start class's static main

        String startClass = argv[curArg++];
        String[] startArgs = new String[argv.length - curArg];

        System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
        invokeStaticMain(startClass, startArgs);
    }

/**
     * Invokes a static "main(argv[]) method on class "className".
     * Converts various failing exceptions into RuntimeExceptions, with
     * the assumption that they will then cause the VM instance to exit.
     *
     * @param className Fully-qualified class name
     * @param argv Argument vector for main()
     */
    private static void invokeStaticMain(String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {

        // 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);

        Class&lt;?&gt; cl;

        try {
            cl = Class.forName(className);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) &amp;&amp; Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

由代码可以看出,在调用函数 invokeStaticMain 的最后会抛出一个异常。

public static class MethodAndArgsCaller extends Exception implements Runnable

回过头再看一下 ZygoteInit 类的 main 函数中的一段代码

catch (MethodAndArgsCaller caller) {
caller.run();
}

其实就是在这个抛出的异常中启动了 SystemServer 类,且这个异常为一个 Runnable 类型,因此 SystemServer 类就运行在 system_server 进程中的一个新的线程里。
二.SystemServer 执行内容

1. 执行 frameworks/base/cmds/system_server/library/system_init.cpp 中的 system_init 函数,启动当前进程,也就是进程 system_server 的 pool thread ,以便执行 Binder IPC 操作。

2. 向 SM(Service Manager) 添加系统服务。
分享到:
评论

相关推荐

    Microsoft SQL Server 2005 Express Edition SP3

    Microsoft SQL Server 2005 Express Edition SQL Server 文档小组无法回答技术支持问题,但是欢迎您对本自述文档提出建议和意见。您可以使用提供的链接快速、直接地发送电子邮件反馈。请使用英语发送您的反馈信息...

    联想Lenovo ThinkSystem SR550服务器 LXCC收集FFDC日志的方法.zip

    联想Lenovo ThinkSystem SR550服务器 LXCC收集FFDC日志的方法

    远程连接不上SQLSERVER

    通常建议在查询分析器里做,因为默认情况下,通过企业管理器注册另外一台SQL Server的超时设置是4秒,而查询分析器是15秒。 修改默认连接超时的方法: 企业管理器-&gt;工具-&gt;选项-&gt;在弹出的"SQL Server企业管理器属性...

    SQL Server 2008管理员必备指南(超高清PDF)Part3

    第14章 分析和监视SQL Server 2008 14.1 监视服务器的性能和活动 14.1.1 监视SQL Server的原因 14.1.2 为监视做准备 14.1.3 监视工具和资源 14.2 使用复制监视器 14.2.1 启动并使用复制监视器 14.2.2 添加发布服务器...

    如果命令返回"无法打开连接"的错误信息,则说明服务器端没有启动 SQL Server 服务,

    检查你的SQL有没有打补丁,没有的话要打上补丁,检查的方法是在查询分析器中运行: select @@version 如果出来的版本号是8.00.760以下,则表明你未安装sp3的补丁,要装上. SQL补丁下载: 全部补丁的位置 ...

    Sqlserver性能调整

    很多客户偶尔会遇到SQL Server 数据库性能...我们提供了按部就班的指导,通过使用可用的工具例如SQL Server Profiler,System Monitor和在SQL Server 2005中新的Dynamic Management View来为一般的性能问题诊断和排错。

    SQL Server 2008管理员必备指南(超高清PDF)Part1

    第14章 分析和监视SQL Server 2008 14.1 监视服务器的性能和活动 14.1.1 监视SQL Server的原因 14.1.2 为监视做准备 14.1.3 监视工具和资源 14.2 使用复制监视器 14.2.1 启动并使用复制监视器 14.2.2 添加发布服务器...

    SQL Server 2008管理员必备指南(超高清PDF)Part2

    第14章 分析和监视SQL Server 2008 14.1 监视服务器的性能和活动 14.1.1 监视SQL Server的原因 14.1.2 为监视做准备 14.1.3 监视工具和资源 14.2 使用复制监视器 14.2.1 启动并使用复制监视器 14.2.2 添加发布服务器...

    Android_启动过程分析

    2. Android-level,由init process 开始,读取init.rc,Native 服务启动,并启动重要的外部程序,例如:servicemanager、Zygote以及System Server。 3. Zygote-Mode,Zygote 启动完SystemServer 后,进入Zygote Mode...

    SQL.Server.2008管理员必备指南.part2.rar(2/4)

     提供实际场景案例分析和故障诊断实验  SQL Server专家的呕心力作,数据库管理员的实战宝典,全面、深入地剖析SQL Server2008新特性,结构独特,实例丰富,操作性强。 编辑本段 目录  第Ⅰ部分 SQL Server 2008...

    图书销售信息系统分析与设计课程设计

    This system is designed for a small bookstore bookstore management information system, the backend database choose SQL SERVER 2000 database of this system, front-end development tool to select the ...

    SQL.Server.2008管理员必备指南.part1.rar(1/4)

     提供实际场景案例分析和故障诊断实验  SQL Server专家的呕心力作,数据库管理员的实战宝典,全面、深入地剖析SQL Server2008新特性,结构独特,实例丰富,操作性强。 编辑本段 目录  第Ⅰ部分 SQL Server 2008...

    诊断SQLSERVER问题常用的日志概述及使用

    作为一个Windows开启和管理的服务程序,Windows会在自己的系统日志system log里记录SQLSERVER这个服务的启动、正常关闭、异常关闭等信息。 SQLSERVER也会把自己的一些概要信息同时记录在Windows的应用程序日志里...

    WinForm+SQLServer酒店管理系统Hotel-Management-System.zip

    这种系统通常涵盖多个方面,包括客房预订、前台管理、客户关系管理、财务管理、员工管理、库存管理、报告和分析等。通过使用酒店管理系统,酒店可以更高效地管理他们的业务,提高客户满意度,优化运营流程,并实现更...

    论文研究-On the Security of a Robust Certified Email System Based on Server-Supported Signature.pdf

    强壮的基于服务器支持的签名认证的电子邮件系统的安全性分析,郭丽峰,,通过认证的电子邮件是标准的电子邮件系统中的增值服务, 它允许发送方以公平的方式将消息传递给接受方。在这个意义上,或者发送��

    SQL.Server.2008管理员必备指南.part3.rar(3/4)

     提供实际场景案例分析和故障诊断实验  SQL Server专家的呕心力作,数据库管理员的实战宝典,全面、深入地剖析SQL Server2008新特性,结构独特,实例丰富,操作性强。 编辑本段 目录  第Ⅰ部分 SQL Server 2008...

    SQL.Server.2008管理员必备指南.part4.rar(4/4)

     提供实际场景案例分析和故障诊断实验  SQL Server专家的呕心力作,数据库管理员的实战宝典,全面、深入地剖析SQL Server2008新特性,结构独特,实例丰富,操作性强。 编辑本段 目录  第Ⅰ部分 SQL Server 2008...

    SQLserver2016-数据库系统概述.pptx

    数据库系统(DataBase System,DBS)由计算机软件、硬件、数据库、 数据库管理系统、数据库应用程序、数据库管理员与用户组成。 用户 用户 用户 数据库应用程序 应用开发工具 数据库管理系统 操作系统 数据库 ...

    联想服务器拆解分析.pptx

    数据源:IDC 2015Q2 X86 Server Market Review 联想服务器拆解分析全文共12页,当前为第5页。 联想企业级产品--市场分析 联想企业级产品--拆解分析 联想服务器拆解分析全文共12页,当前为第6页。 1 总体设计 2 4 3 ...

    access 转 sql server DB_CreateSqlEV1.06 CooSel2.0 CreateSQL

    生成升迁 SQL脚本,保存为 *.sql文件后,SQL2000的查询分析器里调入执行 生成升迁 ASP脚本,这样你可以用该脚本和相应MDB数据库上传到服务器在线升迁 直接执行Access数据导入到SQL2000服务器(表结构和数据) V1.03 ...

Global site tag (gtag.js) - Google Analytics