码迷,mamicode.com
首页 > 移动开发 > 详细

Android源码分析--system_server进程分析

时间:2015-03-07 17:17:38      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:android   源码   系统   

在上一篇博文中我们进行了有关Zygote进程的分析,我们知道Zygote进程创建了一个重要的进程–system_server进程后就进入了无限循环中,之后Android系统中的重要任务就交给了system_server进程,作为zygote的嫡长子进程,system_server进程的意义非凡,今天我们来分析一下system_server进程。

创建system_server进程

在ZygoteInit中main方法中,通过调用startSystemServer方法开启了system_server进程。该方法主要为创建system_server进程准备了一些参数,并调用本地方法forkSystemServer创建system_server进程。让我们来看一下startSystemServer方法的代码:

    private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {

        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=130104352,130104352",
            "--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);

            /* 创建system_server进程 */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* 子进程中执行 */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

这里的代码并不复杂,可以看到,他调用了forkSystemServer方法来创建一个新的进程,之后在子进程,即system_server进程中执行handleSystemServerProcess方法。下面我们来看一下forkSystemServer方法,它是一个native方法对应的源文件在dalvik\vm\native\dalvik_system_Zygote.cpp中。代码如下:

static void Dalvik_dalvik_system_Zygote_forkSystemServer(
        const u4* args, JValue* pResult)
{
    pid_t pid;
    pid = forkAndSpecializeCommon(args, true);

    /* zygote进程检查其子进程是否死掉 */
    if (pid > 0) {
        int status;

        ALOGI("System server process %d has been created", pid);
        gDvm.systemServerPid = pid;
        /*  如果system_server进程退出,则zygote进程也会被杀掉 */
        if (waitpid(pid, &status, WNOHANG) == pid) {
            ALOGE("System server process %d has died. Restarting Zygote!", pid);
            kill(getpid(), SIGKILL);
        }
    }
    RETURN_INT(pid);
}

从代码中可以看到在forkAndSpecializeCommon方法中,我们创建了子进程,并返回了子进程id,接下来我检查如果system_server进程是否退出,若是的话则zygote进程也将会被被干掉,由此可见其重要性。接下来我们来看forkAndSpecializeCommon的代码,这个system_server进程的创建真的是千峰百转啊。。。

static pid_t forkAndSpecializeCommon(const u4* args, bool isSystemServer)
{
    pid_t pid;

    uid_t uid = (uid_t) args[0];
    gid_t gid = (gid_t) args[1];
    ArrayObject* gids = (ArrayObject *)args[2];
    u4 debugFlags = args[3];
    ArrayObject *rlimits = (ArrayObject *)args[4];
    u4 mountMode = MOUNT_EXTERNAL_NONE;
    int64_t permittedCapabilities, effectiveCapabilities;
    char *seInfo = NULL;
    char *niceName = NULL;
    //传入参数isSystemServer为true
    if (isSystemServer) {
        permittedCapabilities = args[5] | (int64_t) args[6] << 32;
        effectiveCapabilities = args[7] | (int64_t) args[8] << 32;
    } else {
       ......
    }

    if (!gDvm.zygote) {
        dvmThrowIllegalStateException(
            "VM instance not started with -Xzygote");

        return -1;
    }
    // 在第一次调用fork函数之前需要调用
    if (!dvmGcPreZygoteFork()) {
        ALOGE("pre-fork heap failed");
        dvmAbort();
    }
    setSignalHandler();
    //向log文件中写入一些数据
    dvmDumpLoaderStats("zygote");
    //子进程被fork出来
    pid = fork();
    if (pid == 0) {
    //在这里根据传入的参数对子进程做出一些处理,例如设置进程名,设置各种id等
    ......
    }

    return pid;
}

至此system_server进程终于被创建出来,我们可以看到system_server进程也是通过Linux系统特有的Fork机制分裂克隆出来的。在fork之前,我们还有一个重要方法没有分析–setSignalHandler方法,该方法用来设置信号处理,下面让我来看一下吧。

static void setSignalHandler()
{
    int err;
    struct sigaction sa;

    memset(&sa, 0, sizeof(sa));

    sa.sa_handler = sigchldHandler;

    err = sigaction (SIGCHLD, &sa, NULL);//设置信号处理函数,该信号是子进程死亡的信号

    if (err < 0) {
        ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
    }
}
static void sigchldHandler(int s)
{
    pid_t pid;
    int status;

    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        /* 打印出我们所关心的进程的死亡状态. */
        ......

        /*
         * 如果刚刚销毁的进程是system_server, 同时杀死zygote进程
         * 这样system_server进程和zygote进程将会被init进程重启
         */
        if (pid == gDvm.systemServerPid) {
            ALOG(LOG_INFO, ZYGOTE_LOG_TAG,
                "Exit zygote because system server (%d) has terminated",
                (int) pid);
            kill(getpid(), SIGKILL);
        }
    }

    if (pid < 0) {
        ALOG(LOG_WARN, ZYGOTE_LOG_TAG,
            "Zygote SIGCHLD error in waitpid: %s",strerror(errno));
    }
}

这里我们发现我们之前已经看到在forkSystemServer方法中已经检查过system_server进程是否死亡,为什么这里还要再一次进行检查?这是为了防止在我们还没有得到fork子进程的pid时,system_server进程就已经死亡的情况。

总结一下:system_server进程的创建经历了漫长的历程:首先startSystemServer中调用了native方法forkSystemServer;之后在native方法forkSystemServer中调用了forkAndSpecializeCommon方法;在forkAndSpecializeCommon方法中fork之前还调用了setSignalHandler来设置信号处理项。这样,我们的system_server进程终于被创建起来,同时他还和zygote进程保持着同生共死的关系。

system_server进程的职责

在startSystemServer的方法中我们可以看到,在创建进程之后,在子进程即system_server进程中会执行handleSystemServerProcess方法,这便是system_server的职责所在,下面我们来看一下:

    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();
        // 设置权限.
        Libcore.os.umask(S_IRWXG | S_IRWXO);
        ......
        if (parsedArgs.invokeWith != null) {
        ......
        } else {
            /* 剩余的参数传递到SystemServer. */
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
        }
    }

可以看到最后system_server进程来到了RuntimeInit中,它的实现在frameworks\base\core\java\com\android\internal\os\RuntimeInit.java中

    public static final void zygoteInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

        //关闭System.out和System.err,使用Android log
        redirectLogStreams();
        //做一些常规初始化
        commonInit();
        //native层初始化,调用此方法之后system_server将与Binder通信系统建立联系,这样就可以使用Binder了
        nativeZygoteInit();

        applicationInit(targetSdkVersion, argv);
    }
    private static void applicationInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        ......
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            // let the process exit
            return;
        }
        invokeStaticMain(args.startClass, args.startArgs);
    }

可以看到,最终我们调用了invokeStaticMain方法,该方法的传入参数在startSystemServer方法中被设置,其传入参数的类名是”com.android.server.SystemServer”

    private static void invokeStaticMain(String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> 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) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /* 抛出的异常在ZygoteInit.main()中被截获 */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }

让我们来看看被截获的语句:

 catch (MethodAndArgsCaller caller) {
            caller.run();//调用了caller的run方法
        } 

run方法代码:

public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }

可以看到,在函数最后抛出异常,在ZygoteInit.main()中被截获,由于传递的参数类名是”com.android.server.SystemServer”,这样我们调用了MethodAndArgsCaller.run()方法去执行了SystemServer类的静态main方法。(关于ZygoteInit可以参考上一篇博文:Android源码分析–Zygote进程分析

    public static void main(String[] args) {
        ......
        // Mmmmmm... more memory!
        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();

        // system server一直在运行, 所以他需要尽可能有效的利用内存
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        Environment.setUserRequired(true);

        System.loadLibrary("android_servers");

        Slog.i(TAG, "Entered the Android system server!");

        // native方法,进行一些传感器服务的初始化
        nativeInit();

        // 创建一个单独的线程,在这里启动系统的各项服务
        ServerThread thr = new ServerThread();
        thr.initAndLoop();
    }

最终,system_server开启了一个新的线程,并执行了它的initAndLoop方法,其也被定义在SystemServer.java中,该方法的代码较多,其主要的工作就是开启了系统中的各项服务,如电池服务,蓝牙服务等等。并调用了Looper的prepareMainLooper方法进行消息循环,然后处理消息,这里不再赘述。

最后,我们来总结一下:

  • 首先system_server执行handleSystemServerProcess方法来完成自己的使命;
  • 之后调用RuntimeInit.zygoteInit方法,在这里我们进行了一些常规的初始化工作已经native层的初始化,从而与Binder通信建立联系;
  • 之后调用invokeStaticMain方法,利用抛出异常的方法在ZygoteInit的main方法中截获并去执行SystemServer的main方法;
  • 在SystemServer的main方法中,我调用nativeInit方法去初始化一些传感器服务,并开启了单独的线程去开启Android系统中的各项服务,并调用了Looper的prepareMainLooper方法进行消息循环,然后处理消息

Android源码分析--system_server进程分析

标签:android   源码   系统   

原文地址:http://blog.csdn.net/smbroe/article/details/44115645

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!