在分析Android系统进入zygote进程一文中知道SystemServer是系统中非常核心的进程

 

SystemServer在ZygoteInit中进行创建,并且启动起来的.代码位置frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

            if (startSystemServer) {    //根据init中传来的参数可知startSystemServer为true                startSystemServer(abiList, socketName);    //启动SystemServer            }

    /**     * Prepare the arguments and fork for the system server process.     */    private static boolean startSystemServer(String abiList, String socketName)            throws MethodAndArgsCaller, RuntimeException {    //.......        /* Hardcoded command line to start the system server */        String args[] = {         //准备启动System Server所需要的参数            "--setuid=1000",            "--setgid=1000",            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",            "--capabilities=" + capabilities + "," + capabilities,            "--nice-name=system_server",   //进程的名字为system_server            "--runtime-args",            "com.android.server.SystemServer",    //包名        };        ZygoteConnection.Arguments parsedArgs = null;        int pid;        try {            parsedArgs = new ZygoteConnection.Arguments(args);    //通过ZygoteConnection对参数进行封装            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);            /* Request to fork the system server process */             pid = Zygote.forkSystemServer(    //请求孵化SystemServer进程, 将创建的进程号赋值给pid                    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的子进程            if (hasSecondZygote(abiList)) {                waitForSecondaryZygote(socketName);  //等待zygote第二阶段            }            handleSystemServerProcess(parsedArgs);    //运行SystemServer,之后SystemServer就与Zygote分道扬镳,在自己的进程中运行        }        return true;    }
下面将分两部分讲解进入SystemServer流程:

1.创建SystemServer进程

2.运行SystemServer进程

创建SystemServer进程

Zygote调用forkSystenServer函数来进行创建SystemServer进程,具体代码位置frameworks/base/core/java/com/android/internal/os/Zygote.java

    /* @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) {        VM_HOOKS.preFork();      //将所有守护进程停止运行        int pid = nativeForkSystemServer(     //调用native函数孵化进程                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);        // Enable tracing as soon as we enter the system_server.        if (pid == 0) {            Trace.setTracingEnabled(true);   //进入SystemServer进程,可以输出trace        }        VM_HOOKS.postForkCommon();   //重新运行各个守护进程        return pid;    }    native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

通过JNI调用到native函数中,代码位置frameworks/base/core/com_android_internal_os_Zygote.cpp

static jint com_android_internal_os_Zygote_nativeForkSystemServer(        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,        jlong effectiveCapabilities) {  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,    ///孵化进程                                      debug_flags, rlimits,                                      permittedCapabilities, effectiveCapabilities,                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,                                      NULL, NULL);  if (pid > 0) {        //pid大于0为父进程, 检查子进程是否已经死掉      // The zygote process checks whether the child process has died or not.      ALOGI("System server process %d has been created", pid);    //输出SystemServer进程信息      gSystemServerPid = 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.      int status;      if (waitpid(pid, &status, WNOHANG) == pid) {       //判断子进程是否死掉, 如果死掉重启zygote          ALOGE("System server process %d has died. Restarting Zygote!", pid);          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");      }  }  return pid;}

调用底层进行fork system server,在JNI中主要通过函数ForkAndSpecializeCommon中调用fork()函数孵化SystemServer进程。

Fork函数其实就是使用Linux调用fork创建进程。如果创建出的进程pid为0,说明新进程为Zygote的子进程,系统会为他设置uid,gid等参数。新创建进程的pid大于0的话,说明该进程为进程SystemServer的进程号,Zygote进程会检查一下该进程有没有died,如果进程died了就会重新启动Zygote进程。SystemServer进程创建完成后,就会重新启动垃圾回收后台进程。之后回到ZygoteInit中,SystemServer进程就与Zygote进程正式分道扬镳,pid=0为子进程,以后的代码都运行在了SystemServer进程中了

// Utility routine to fork zygote and specialize the child process.static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,                                     jint debug_flags, jobjectArray javaRlimits,                                     jlong permittedCapabilities, jlong effectiveCapabilities,                                     jint mount_external,                                     jstring java_se_info, jstring java_se_name,                                     bool is_system_server, jintArray fdsToClose,                                     jstring instructionSet, jstring dataDir) {  SetSigChldHandler();#ifdef ENABLE_SCHED_BOOST  SetForkLoad(true);#endif  pid_t pid = fork();    //孵化进程  if (pid == 0) {    // The child process.    gMallocLeakZygoteChild = 1;    // Clean up any descriptors which must be closed immediately    DetachDescriptors(env, fdsToClose);    // Keep capabilities across UID change, unless we're staying root.    if (uid != 0) {      EnableKeepCapabilities(env);    }   //........    if (!is_system_server) {        int rc = createProcessGroup(uid, getpid());        if (rc != 0) {            if (rc == -EROFS) {                ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");            } else {                ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));            }        }    }    SetGids(env, javaGids);    SetRLimits(env, javaRlimits);    //...    rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);  //设置selinux安全上下文    //....  } else if (pid > 0) {    // the parent process#ifdef ENABLE_SCHED_BOOST    // unset scheduler knob    SetForkLoad(false);#endif  }  return pid;}}  // anonymous namespace

运行SystemServer

根据上文分析创建完成SystemServer后会调用函数handleSystemServerProcess处理,继续其未完成的使命。


当Zygote复制出新的进程时,由于复制出的新进程与Zygote进程共享内存空间,而在Zygote进程中创建的服务端Socket是新进程不需要的,所以新创建的进程需要关闭该Socket服务端。系统会将该进程的名字赋值为system_server,我们可以通过ps命令查看。

    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.        Os.umask(S_IRWXG | S_IRWXO);        if (parsedArgs.niceName != null) {            Process.setArgV0(parsedArgs.niceName);  //设置进程的名字        }        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");  //获取systemServerClasspath        if (systemServerClasspath != null) {            performSystemServerDexOpt(systemServerClasspath);   //对该路径中的文件做dexopt优化        }        if (parsedArgs.invokeWith != null) {   //invokeWith为空故走else            String[] args = parsedArgs.remainingArgs;            // If we have a non-null system server class path, we'll have to duplicate the            // existing arguments and append the classpath to it. ART will handle the classpath            // correctly when we exec a new process.            if (systemServerClasspath != null) {                String[] amendedArgs = new String[args.length + 2];                amendedArgs[0] = "-cp";                amendedArgs[1] = systemServerClasspath;                System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);            }            WrapperInit.execApplication(parsedArgs.invokeWith,                    parsedArgs.niceName, parsedArgs.targetSdkVersion,                    VMRuntime.getCurrentInstructionSet(), null, args);        } else {            ClassLoader cl = null;            if (systemServerClasspath != null) {                cl = createSystemServerClassLoader(systemServerClasspath,                                                   parsedArgs.targetSdkVersion);  //为systemServer创建ClassLoader, 让他可以进入平台的私有本地类库                Thread.currentThread().setContextClassLoader(cl);            }            /*             * Pass the remaining arguments to SystemServer.             */            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);    //调用到RuntimeInit中        }        /* should never reach here */    }
classPath中的内容为systemServerClasspath = /system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar三个jar包, 之后会将这三个jar从路径中获取出来,判断是否要进行dexopt优化. 如果需要就调用installer进行优化. apk/jar做dexopt会在后文详细讲解 TODO.

    /**     * Performs dex-opt on the elements of {@code classPath}, if needed. We     * choose the instruction set of the current runtime.     */    private static void performSystemServerDexOpt(String classPath) {        final String[] classPathElements = classPath.split(":");  //将所需要优化的元素保存在string数组中        final InstallerConnection installer = new InstallerConnection();        installer.waitForConnection();        final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();        try {            String sharedLibraries = "";            for (String classPathElement : classPathElements) {                // System server is fully AOTed and never profiled                // for profile guided compilation.                // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?                final int dexoptNeeded = DexFile.getDexOptNeeded(  //调用DexFile判断该元素是否要进行dexopt优化                        classPathElement, instructionSet, "speed",                        false /* newProfile */);                if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {  //如果返回值不为NO_DEXOPT_NEEDED就进行优化                    installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,                            dexoptNeeded, 0 /*dexFlags*/, "speed", null /*volumeUuid*/,                            sharedLibraries);                }                if (!sharedLibraries.isEmpty()) {                    sharedLibraries += ":";                }                sharedLibraries += classPathElement;            }        } catch (IOException | InstallerException e) {            throw new RuntimeException("Error starting system_server", e);        } finally {            installer.disconnect();        }    }

上面工作完成之后, 根据systemServerClasspath创建classLoader, 最后,将启动SystemServer的参数解析完剩余的参数“com.android.server.SystemServer”保存在remainingArgs中,并将参数传入RuntimeInit中。代码位置frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)            throws ZygoteInit.MethodAndArgsCaller {        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");        redirectLogStreams();   //初始化Android LOG输出流, 并且将system.out, system.err关闭, 将两者重新定向到Android log中             commonInit();    //初始化运行环境        nativeZygoteInit();   //创建BInder线程池        applicationInit(targetSdkVersion, argv, classLoader);    }
    private static final native void nativeZygoteInit();  //jni调用

通过JNI调用到AndroidRuntime.cpp中,代码位置framework/base/core/jni/AndroidRuntime.cpp

static AndroidRuntime* gCurRuntime = NULL;static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz){    gCurRuntime->onZygoteInit();    //调用onZygoteInit函数}/* * JNI registration. */static const JNINativeMethod gMethods[] = {    { "nativeFinishInit", "()V",        (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },    { "nativeZygoteInit", "()V",        (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },   //JNI注册函数, nativeZygoteInit对应的jni函数    { "nativeSetExitWithoutCleanup", "(Z)V",        (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },};
由于app_main.cpp为AndroidRuntime的子类, 所以就调用到app_main中的onZygoteInit函数,具体代码位置frameworks/base/cmds/app_process/app_main.cpp
    virtual void onZygoteInit()    {        sp proc = ProcessState::self();   //创建ProcessState        ALOGV("App process: starting thread pool.\n");        proc->startThreadPool();     //启动线程池    }
代码位置frameworks/native/libs/binder/ProcessState.cpp

void ProcessState::startThreadPool(){    AutoMutex _l(mLock);    if (!mThreadPoolStarted) {        mThreadPoolStarted = true;        spawnPooledThread(true);  //开始孵化线程池    }}void ProcessState::spawnPooledThread(bool isMain){    if (mThreadPoolStarted) {  //变量为true        String8 name = makeBinderThreadName();  //获取binder的name        ALOGV("Spawning new pooled thread, name=%s\n", name.string());        sp t = new PoolThread(isMain);        t->run(name.string());   //将binder放入线程池, 运行线程    }}String8 ProcessState::makeBinderThreadName() {    int32_t s = android_atomic_add(1, &mThreadPoolSeq);    pid_t pid = getpid();    //获取进程pid    String8 name;    name.appendFormat("Binder:%d_%X", pid, s);  //为binder命名    return name;}
之后调用applicationInit函数,继续向SystemServer中挺进.

    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)            throws ZygoteInit.MethodAndArgsCaller {        //...........        final Arguments args;        try {            args = new Arguments(argv);    //将argv参数封装到Argument中        } catch (IllegalArgumentException ex) {            Slog.e(TAG, ex.getMessage());            // let the process exit            return;        }        // The end of of the RuntimeInit event (see #zygoteInit).        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);        // Remaining arguments are passed to the start class's static main        invokeStaticMain(args.startClass, args.startArgs, classLoader);    //args.startClass为com.android.Server.SystemServer    }
 在调用入口函数invokeStaticMain之前会将从ZygoteInit中传过来的参数进行处理,将com.android.server.SystemServer赋值给startClass,之后进入进程入口函数:

    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)            throws ZygoteInit.MethodAndArgsCaller {        Class<?> cl;        try {            cl = Class.forName(className, true, classLoader); //通过反射获得SystemServer的class        } 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 });   //通过反射获取SystemServer的main函数        } 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))) {  //如果main函数不是静态公共的将会抛出异常            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异常,并在ZygoteInit.main中捕获该异常。这样就可以清除应用程序进程在创建过程中的调用栈。将应用程序入口设置为SystemServer的main函数。
    public static void main(String argv[]) {        //.....        try {         //.....        } catch (MethodAndArgsCaller caller) {            caller.run();   //在函数中捕获异常, 并调用MethodAndArgsCaller的run函数        } catch (RuntimeException ex) {            Log.e(TAG, "Zygote died with exception", ex);            closeServerSocket();            throw ex;        }    }
其实MethodAndArgsCaller继承于Exception,并且实现于Runnable.

    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;      //构造函数, 将SystemServer的main函数赋值给mMethod            mArgs = args;        }        public void run() {            try {                mMethod.invoke(null, new Object[] { mArgs });    //执行SystemServer的main函数, 从而进入到SystemServer中            } catch (IllegalAccessException ex) {                throw new RuntimeException(ex);            } catch (IllegalArgumentException 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);            }        }    }

后文将继续讲解进入SystemServer后系统做了那些事情.

更多相关文章

  1. Surface与SurfaceHolder.Callback
  2. Android(安卓)-- 网络管理分析
  3. Android--进程常驻
  4. Android(安卓)WebView 使用总结--持续更新
  5. Android6.0 SystemUI之网络信号栏显示刷新
  6. 优化 Android(安卓)Studio 启动、编译、运行速度的方法
  7. Android与JS交互之基本
  8. 使用MediaPlayer播放声音的异常
  9. Android(安卓)Studio AIDL实现

随机推荐

  1. 令人崩溃的新浪微博 java SDK
  2. Android新浪星座运势程序开发
  3. Android重力感应示例
  4. Android程序开发入门——进程生命周期
  5. Android事件分发机制--ViewGroup(二)
  6. 使用多字节字符集的跨平台(PC、Android、I
  7. Android(安卓)手势小试牛刀
  8. 关于多设备登录的思考与实现
  9. Android(安卓)屏幕适配问题
  10. 短视频技术详解:Android端的短视频开发技