Android SystemServer的创建过程

SystemServer进程是有Zygote fork出来的一个进程,下面来看看zygote进程的执行过程

frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
   // zygote进程是由init进程通过fork而来
    AppRuntime runtime;

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");
    }
}

/frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const char* options)
{
    /*
     * We want to call main() with a String array with arguments in it.
     * At present we have two arguments, the class name and an option string.
     * Create an array to hold them.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    jstring optionsStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(2, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    optionsStr = env->NewStringUTF(options);
    env->SetObjectArrayElement(strArray, 1, optionsStr);

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className);
    // 得到"com.android.internal.os.ZygoteInit"类
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    } else {
        // 得到ZygoteInit类的main方法
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
        } else {
            // 调用ZygoteInit类的main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

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

下面就进入到了com.android.internal.os.ZygoteInit的main方法中。

public static void main(String argv[]) {  
    try {  
        ……  
        // 启动SystemServer
        if (argv[1].equals("start-system-server")) {  
            startSystemServer();  
        }   
        ……  
    } catch (MethodAndArgsCaller caller) {  
        caller.run();  
    } catch (RuntimeException ex) {  
        ……  
    }  
} 
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(
                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) {
        handleSystemServerProcess(parsedArgs);
    }

    return true;
}

设置进程的参数是system_server,对应的类是com.android.server.SystemServer。
Zygote.forkSystemServer真正地fork一个进程,参数前面已经设置好了,所以,这个fork出来的进程就是system_server,而这个进程是zygote的子进程

创建得到SystemServer进程之后,下面执行handleSystemServerProcess方法。

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

    // 修改进程名为system_server  
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }

    if (parsedArgs.invokeWith != null) {
        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                null, parsedArgs.remainingArgs);
    } else {
        //最终会调用该方法
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
    }
}

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

    redirectLogStreams();
    // 做一些常规初始化  
    commonInit();
    // native层的初始化  
    nativeZygoteInit();
    // 调用应用程序java层的main 方法
    applicationInit(targetSdkVersion, argv);
}
private static void applicationInit(int targetSdkVersion, String[] argv)  
            throws ZygoteInit.MethodAndArgsCaller {  
        nativeSetExitWithoutCleanup(true);  

        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());  
            return;  
        }  

        // 调用传递过来的类的静态main方法
        invokeStaticMain(args.startClass, args.startArgs);  
} 
private static void invokeStaticMain(String className, String[] argv)  
            throws ZygoteInit.MethodAndArgsCaller {  
        Class<?> cl;  

        try {  
            // 加载com.android.server.SystemServer这个类  
            cl = Class.forName(className);  
        } catch (ClassNotFoundException ex) {  
            throw new RuntimeException(  
                    "Missing class when invoking static main " + className,  
                    ex);  
        }  

        Method m;  
        try {  
            // 获得main方法  
            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();  
        // 判断main函数的类型  
        if (! (Modifier.isStatic(modifiers) && 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);  
}  

ZygoteInit.MethodAndArgsCaller是一个继承自Exception的类,invokeStaticMain最后并没有直接调用com.android.server.SystemServer的main 方法,而是抛出了一个ZygoteInit.MethodAndArgsCalle类型的异常。

public static void main(String argv[]) {  
    try {  
        ……  

        if (argv[1].equals("start-system-server")) {  
            startSystemServer();  
        }   
        ……  
    } catch (MethodAndArgsCaller caller) {  
        caller.run();  
    } catch (RuntimeException ex) {  
        ……  
    }  
} 

main函数中通过try-catch最终捕获到了MethodAndArgsCaller异常,并通过异常类的run函数来处理。

public static class MethodAndArgsCaller extends Exception  
            implements Runnable {  
    /** method to call */  
    private final Method mMethod;  

    /** argument array */  
    private final String[] mArgs;  

    // 构造函数将参数保存下来      
    public MethodAndArgsCaller(Method method, String[] args) {  
            mMethod = method;  
            mArgs = args;  
        }  

        // run函数调用main函数  
    public void run() {  
            try {  
                mMethod.invoke(null, new Object[] { mArgs });  
            } catch (IllegalAccessException ex) {  
                throw new RuntimeException(ex);  
            } catch (InvocationTargetException ex) {  
                ……  
            }  
        }  
    }  
}

参考文章:
http://blog.csdn.net/hu3167343/article/details/38375167

欢迎关注微信公众号:DroidMind
精品内容独家发布平台


呈现与博客不一样的技术干货

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值