Android系统启动——SystemServer进程启动

基于Android 7.0源码,分析system_server进程的启动过程。

  在文章《Android系统启动——Zygote进程》中讲到,Zygote启动过程中会调用startSystemServer()启动system_server进程。SystemServer是由Zygote fork生成的,进程名为system_server,该进程承载着framework的核心服务。
  下面从startSystemServer()开始讲解详细启动流程。

ZygoteInit.startSystemServer
    Zygote.forkSystemServer
        Zygote.nativeForkSystemServer
        com_android_internal_os_Zygote_nativeForkSystemServer //com_android_internal_os_Zygote_nativeForkSystemServer.cpp文件中
            ForkAndSpecializeCommon //com_android_internal_os_Zygote_nativeForkSystemServer.cpp文件中
------------------------------------------------------------
该分界线上方处于zygote进程      下方则运行在system_server进程
------------------------------------------------------------
    ZygoteInit.handleSystemServerProcess
        ZygoteInit.performSystemServerDexOpt
        RuntimeInit.zygoteInit
            RuntimeInit.commonInit()
            RuntimeInit.nativeZygoteInit()
            RuntimeInit.applicationInit
                RuntimeInit.invokeStaticMain
                    SystemServer.main

1、ZygoteInit.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(String abiList, String socketName)
        throws MethodAndArgsCaller, RuntimeException {
    long capabilities = posixCapabilitiesAsBits(
        OsConstants.CAP_IPC_LOCK,
        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
    );
    /* Containers run without this capability, so avoid setting it in that case */
    if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
        capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
    }
    /* 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,1021,1032,3001,3002,3003,3006,3007,3009,3010",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "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);//对zygote进程进行fork,得到的子进程就是SystemServer进程,返回的子进程pid为0
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    if (pid == 0) {//子进程ystem_server进程pid为0,此时位于system_server进程中
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        handleSystemServerProcess(parsedArgs);
    }

    return true;
}

2、Zygote.forkSystemServer

[===>frameworks\base\core\java\com\android\internal\os\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) {
    VM_HOOKS.preFork();
    int pid = nativeForkSystemServer(//调用native方法nativeForkSystemServer来fork system_server进程
            uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
    // Enable tracing as soon as we enter the system_server.
    if (pid == 0) {
        Trace.setTracingEnabled(true);
    }
    VM_HOOKS.postForkCommon();
    return pid;
}

  还记不记得文章《Android系统启动——Zygote进程》中在执行AndroidRuntime.start函数时startVm创建虚拟机后又startReg对jni函数进行了注册?
  那么nativeForkSystemServer()这个native方法就是在这个过程中注册的,然后调用com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法完成nativeForkSystemServer()与com_android_internal_os_Zygote_nativeForkSystemServer()方法的一一映射关系,也就是会进入下面的方法。

3、nativeForkSystemServer

4、com_android_internal_os_Zygote_nativeForkSystemServer

[===>frameworks\base\core\jni\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);//在zygote进程中,返回的是system_server进程的pid
  if (pid > 0) {//zygote进程处理
      // The zygote process checks whether the child process has died or not.
      ALOGI("System server process %d has been created", pid);
      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) {//等待进程id为pid的进程死亡,这里就是等待system_server进程死亡
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");//重启zygote进程
      }
  }
  return pid;
}

  当system_server进程死亡了,会重启zygote进程。
  在文章《Android系统启动——Zygote进程》的开始我们讲到属性ro.zygote,这个属性目前可能有四个不同的值:

ro.zygote值init.rc文件名
zygote32init.zygote32.rc
zygote64init.zygote64.rc
zygote32_64init.zygote32_64.rc
zygote64_32init.zygote64_32.rc

  在文章《Android系统启动——Zygote进程》我们只是分析了init.zygote32.rc的情况,init.zygote64.rc与之类似。
  但是自从Android 5.0就开始支持了64bit程序,因此系统启动时会生成两个zygote进程:zygote与zygote64。这里我就以ro.zygote=zygote64_32为例,先来看看init.zygote64_32.rc文件。

# zygote64进程 fork出system_server,system_server死亡后只会重启zygote64
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks /sys/fs/cgroup/stune/foreground/tasks

# zygote进程
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
    class main
    socket zygote_secondary stream 660 root system
    onrestart restart zygote #zygote32进程挂掉,则system_server、zygote和zygote64进程都会重启
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

  在\frameworks\base\cmds\app_process中会生成两个bin文件app_process64和app_process32。在上面的这个情况下,可以先做出推断:
- kill system_server进程,只会重启zygote64进程和system_server进程
- kill zygote64进程,只会重启zygote64进程和system_server进程
- kill zygote进程,zygote、zygote64和system_server进程都会重启

  好了,推断做了,来看看实际情况如何,选用了一台运行Android6.0.1系统的手机,ro.zygote属性值为zygote64_32,如下:

ro.zygote

  正常状态下,其zygote、zygote64和system_server进程的状态如下(省略了其他进程,下同):

USER      PID   PPID  VSIZE  RSS   WCHAN              PC  NAME
root      1     0     2100   1388  SyS_epoll_ 00004b0ad8 S /init
root      533   1     2094300 76112 poll_sched 7f9d399cc4 S zygote64
root      534   1     1525140 64556 poll_sched 00f6f3ae3c S zygote
system    1430  533   2358700 170720 SyS_epoll_ 7f9d399ba4 S system_server

  在adb shell后,输入”kill 1430”,杀system_server进程过后,system_server和zygote64的pid变化了,表示它俩system_server和zygote64进程都重启了:

USER      PID   PPID  VSIZE  RSS   WCHAN              PC  NAME
root      1     0     2100   1392  SyS_epoll_ 00004b0ad8 S /init
root      534   1     1525140 64716 poll_sched 00f6f3ae3c S zygote
root      17326 1     2094316 75972 poll_sched 7f79aaacc4 S zygote64
system    17574 17326 2288376 118804 SyS_epoll_ 7f79aaaba4 S system_server

  紧接着输入”kill 17326”,杀zygote64进程过后,system_server和zygote64的pid又变化了,表示它俩system_server和zygote64进程都重启了:

USER      PID   PPID  VSIZE  RSS   WCHAN              PC  NAME
root      1     0     2100   1392  SyS_epoll_ 00004b0ad8 S /init
root      534   1     1525140 64872 poll_sched 00f6f3ae3c S zygote
root      19820 1     2094312 76016 poll_sched 7f89f0bcc4 S zygote64
system    20129 19820 2308512 121012 SyS_epoll_ 7f89f0bba4 S system_server

  紧接着输入”kill 534”,杀zygote进程过后,system_server、zygote和zygote64进程的pid都变化了,表示system_server、zygote和zygote64进程都重启了:

USER      PID   PPID  VSIZE  RSS   WCHAN              PC  NAME
root      1     0     2100   1392  SyS_epoll_ 00004b0ad8 S /init
root      22286 1     1525144 64432 poll_sched 00f6f29e3c S zygote
root      22287 1     2094320 75980 poll_sched 7fb76fdcc4 S zygote64
system    22590 22287 2287100 119392 SyS_epoll_ 7fb76fdba4 S system_server

  事实证明,之前的三个推断是正确的。
  好了,回来继续看system_server进程的fork过程,看看ForkAndSpecializeCommon函数。

5、ForkAndSpecializeCommon

[===>frameworks\base\core\jni\com_android_internal_os_Zygote.cpp]

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

  ...

  pid_t pid = fork();

  if (pid == 0) {//system_server进程
    // The child process.
    gMallocLeakZygoteChild = 1;

    ...

    // Make it easier to debug audit logs by setting the main thread's name to the
    // nice name rather than "app_process".
    if (se_info_c_str == NULL && is_system_server) {
      se_name_c_str = "system_server";
    }
    if (se_info_c_str != NULL) {
      SetThreadName(se_name_c_str);//设置进程名为system_server,方便debug
    }

    ...
  } else if (pid > 0) {//zygote进程
    // the parent process
    ...

  }
  return pid;
}

  fork()创建新进程时,会有两次return,对于pid==0为子进程的返回,对于pid>0为父进程的返回。 到此,system_server进程已完成了创建的所有工作,接下来开始了system_server进程的真正工作。在前面startSystemServer()方法中,zygote进程执行完forkSystemServer()后,新创建出来的system_server进程便进入handleSystemServerProcess()方法。至于fork()的过程,后面再专门写一篇文章吧。

6、ZygoteInit.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();//在fork过程中复制了原来位于zygote进程的socket服务端,这里关闭从父进程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);//设置当前进程名为“system_server”
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");//获取环境变量SYSTEMSERVERCLASSPATH,环境变量位于init.environ.rc中
    if (systemServerClasspath != null) {
        performSystemServerDexOpt(systemServerClasspath);//对环境变量SYSTEMSERVERCLASSPATH中的jar包进行dex优化
    }

    if (parsedArgs.invokeWith != null) {//zygote的启动参数未包含“--invoke-with”,故本条件不成立
        ...

        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = createSystemServerClassLoader(systemServerClasspath,
                                               parsedArgs.targetSdkVersion);

            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         */
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }

    /* should never reach here */
}

  Android中的环境变量是由init进程启动过程中读取/system/core/rootdir/init.environ.rc.in文件设置的,具体过程请参考《Android系统启动——init进程》。
  环境变量SYSTEMSERVERCLASSPATH是由PRODUCT_SYSTEM_SERVER_CLASSPATH变量指定:

# system/core/rootdir/Android.mk文件中
# Regenerate init.environ.rc if PRODUCT_BOOTCLASSPATH has changed.
bcp_md5 := $(word 1, $(shell echo $(PRODUCT_BOOTCLASSPATH) $(PRODUCT_SYSTEM_SERVER_CLASSPATH) | $(MD5SUM)))
bcp_dep := $(intermediates)/$(bcp_md5).bcp.dep
$(bcp_dep) :
        $(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.bcp.dep && touch $@

$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/init.environ.rc.in $(bcp_dep)
        @echo "Generate: $< -> $@"
        @mkdir -p $(dir $@)
        $(hide) sed -e 's?%BOOTCLASSPATH%?$(PRODUCT_BOOTCLASSPATH)?g' $< >$@
        $(hide) sed -i -e 's?%SYSTEMSERVERCLASSPATH%?$(PRODUCT_SYSTEM_SERVER_CLASSPATH)?g' $@
        $(hide) sed -i -e 's?%EXPORT_GLOBAL_ASAN_OPTIONS%?$(EXPORT_GLOBAL_ASAN_OPTIONS)?g' $@

  而PRODUCT_SYSTEM_SERVER_CLASSPATH由PRODUCT_SYSTEM_SERVER_JARS决定:

# build/core/dex_preopt.mk文件中
PRODUCT_SYSTEM_SERVER_CLASSPATH := $(subst $(space),:,$(foreach m,$(PRODUCT_SYSTEM_SERVER_JARS),/system/framework/$(m).jar))

  PRODUCT_SYSTEM_SERVER_JARS变量的值可以根据具体产品的需要进行增减。
  OK,在获取到环境变量SYSTEMSERVERCLASSPATH指定的jar包们后,就要对这些jar包进行dex优化了。

7、performSystemServerDexOpt

[===>frameworks/base/core/java/com/android/internal/os/ZygoteInit.java]

/**
 * 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(":");
    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(
                    classPathElement, instructionSet, "speed",
                    false /* newProfile */);
            if (dexoptNeeded != DexFile.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指定的jar包进行dex优化后,就执行RuntimeInit.zygoteInit了。

8、RuntimeInit.zygoteInit

[===>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();//日志重定向

    commonInit();//通用的初始化工作
    nativeZygoteInit();//zygote初始化
    applicationInit(targetSdkVersion, argv, classLoader);//应用的初始化工作
}

9、RuntimeInit.commonInit

[===>frameworks/base/core/java/com/android/internal/os/RuntimeInit.java]

private static final void commonInit() {
    if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");

    /* set default handler; this applies to all threads in the VM */
    Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());// 设置默认的未捕捉异常处理方法

    /*
     * Install a TimezoneGetter subclass for ZoneInfo.db
     */
    TimezoneGetter.setInstance(new TimezoneGetter() {
        @Override
        public String getId() {
            return SystemProperties.get("persist.sys.timezone");
        }
    });
    TimeZone.setDefault(null);//设置默认时区

    /*
     * Sets handler for java.util.logging to use Android log facilities.
     * The odd "new instance-and-then-throw-away" is a mirror of how
     * the "java.util.logging.config.class" system property works. We
     * can't use the system property here since the logger has almost
     * certainly already been initialized.
     */
    LogManager.getLogManager().reset();
    new AndroidConfig();

    /*
     * Sets the default HTTP User-Agent used by HttpURLConnection.
     */
    String userAgent = getDefaultUserAgent();
    System.setProperty("http.agent", userAgent);//设置默认的HTTP User-agent

    /*
     * Wire socket tagging to traffic stats.
     */
    NetworkManagementSocketTagger.install();

    /*
     * If we're running in an emulator launched with "-trace", put the
     * VM into emulator trace profiling mode so that the user can hit
     * F9/F10 at any time to capture traces.  This has performance
     * consequences, so it's not something you want to do always.
     */
    String trace = SystemProperties.get("ro.kernel.android.tracing");
    if (trace.equals("1")) {
        Slog.i(TAG, "NOTE: emulator trace profiling enabled");
        Debug.enableEmulatorTraceOutput();
    }

    initialized = true;
}

10、nativeZygoteInit

[===>frameworks/base/core/jni/AndroidRuntime.cpp]

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

11、RuntimeInit.applicationInit

[===>frameworks/base/core/java/com/android/internal/os/RuntimeInit.java]

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        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;
    }

    // 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);//调用startClass的static方法 main(),此处args.startClass为“com.android.server.SystemServer”
}

12、invokeStaticMain

[===>frameworks/base/core/java/com/android/internal/os/RuntimeInit.java]

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    Class<?> cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } 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);
    }

    /*
     * 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);//此时,m描述的是SystemServer类的main函数
}

  这里以Class.forName的方式获取到SystemServer类及其main函数。
  注意该函数最后一句抛出异常的语句,根据注释,这个ZygoteInit.MethodAndArgsCaller的“异常”会被ZygoteInit.main()捕获,并且会触发执行异常类的run方法。

  那么就回过头来看看ZygoteInit.main()函数的代码呗。

public static void main(String argv[]) {
    ...

    try {
        ...
    } catch (MethodAndArgsCaller caller) {
        caller.run();
    } catch (RuntimeException ex) {
        ...
    }
}

  哦哦哦,这里RuntimeInit.applicationInit有抛出ZygoteInit.MethodAndArgsCaller“异常”,然后在ZygoteInit.main()中进行捕获,不过需要注意的是由于在执行handleSystemServerProcess开始就处于system_server进程了,因此捕获ZygoteInit.MethodAndArgsCaller“异常”的进程是system_server进程,捕获后就会调用MethodAndArgsCaller.run。

13、MethodAndArgsCaller.run

[===>frameworks/base/core/java/com/android/internal/os/ZygoteInit.java]

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;//此时,method描述的是SystemServer类的main函数
        mArgs = args;
    }

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

  终于,zygote启动system_server进程的流程已经一步步的简要分析完了,后面就是通过反射机制进入到SystemServer.main中,进行类似与初始化的工作内容了,这个篇幅放到下篇文章《Android系统启动——SystemServer进程初始化》中了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值