Android System Server进程源码分析 上

来源:互联网 发布:java邮箱格式验证方法 编辑:程序博客网 时间:2024/06/04 18:14

http://blog.csdn.net/xichangbao/article/details/53131428

一 System Server

System Server是Zygote启动的第一个进程,它的核心功能是启动和管理Android系统的各类服务。

1.0 startSystemServer

private static boolean startSystemServer(String abiList, String socketName) // abiList为arm64-v8a,socketName为zygote
        throws MethodAndArgsCaller, RuntimeException {
    long capabilities = posixCapabilitiesAsBits( // Linux的Capabilities安全机制,可参考include/uapi/linux/capability.h
        OsConstants.CAP_BLOCK_SUSPEND, // 允许阻止系统挂起
        OsConstants.CAP_KILL, // 允许对不属于自己的进程发送信号
        OsConstants.CAP_NET_ADMIN, // 允许执行网络管理任务
        OsConstants.CAP_NET_BIND_SERVICE, // 允许绑定到小于1024的端口
        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 // 允许配置TTY设备
    );
    /* 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", // 进程名是system_server
        "--runtime-args",
        "com.android.server.SystemServer",
    };
    ZygoteConnection.Arguments parsedArgs = null;

    int pid;

    try {
        parsedArgs = new ZygoteConnection.Arguments(args); // 将参数转化为Arguments格式
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

        /* Request to fork the system server process */
        pid = Zygote.forkSystemServer( // // fork system_server进程
                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) { // fork返回0,说明在子进程(system_server)中
        if (hasSecondZygote(abiList)) { // 判断是否存在第二个zygote需要启动,由于64位系统为了兼容32位应用程序,将同时启动zygote64和zygote,所以这里为true
            waitForSecondaryZygote(socketName); // 等待zygote_secondary启动完成
        }

        handleSystemServerProcess(parsedArgs); // 完成system_server进程剩余的工作
    }

    return true;
}

二 forkSystemServer

2.0 forkSystemServer
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方法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); // 在system_server进程中重新使能Systrace追踪
    }
    VM_HOOKS.postForkCommon();
    return pid;
}

public void preFork() {
    Daemons.stop();  // 停止HeapTaskDaemon、ReferenceQueueDaemon、FinalizerDaemon、FinalizerWatchdogDaemon等四个Daemon子线程
    waitUntilAllThreadsStopped();  // 等待所有子线程结束
    token = nativePreFork(); // 完成一些运行时fork前期工作
}

public void postForkCommon() {
    Daemons.start();  // 启动HeapTaskDaemon、ReferenceQueueDaemon、FinalizerDaemon、FinalizerWatchdogDaemon等四个Daemon子线程
}

2.1 com_android_internal_os_Zygote_nativeForkSystemServer

nativeForkSystemServer对应JNI函数是com_android_internal_os_Zygote_nativeForkSystemServer
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);  // fork子进程
  if (pid > 0) {  // fork返回大于0,说明在父进程(zygote64)中
      // 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) {  // 等待子进程退出,WNOHANG表示非阻塞 // 这里是处理system_server刚创建就crash的情况
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!"); // 当system_server进程死亡后,需要重启zygote进程
      }
  }
  return pid;
}


2.2 ForkAndSpecializeCommon

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(); // 设置SIGCHLD信号处理函数 // 子进程的SIGCHLD信号处理函数会在后面改回系统默认函数

#ifdef ENABLE_SCHED_BOOST
  SetForkLoad(true);
#endif

  pid_t pid = fork(); // fork子进程

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

    // Clean up any descriptors which must be closed immediately
    DetachDescriptors(env, fdsToClose); // 关闭并清除文件描述符 // 由于fdsToClose为null,所以没有关闭任何文件描述符

    // Keep capabilities across UID change, unless we're staying root.
    if (uid != 0) {
      EnableKeepCapabilities(env); // 非root用户,禁止动态改变进程的权限
    }

    DropCapabilitiesBoundingSet(env); // 取消进程的已有的Capabilities权限

    bool use_native_bridge = !is_system_server && (instructionSet != NULL)
        && android::NativeBridgeAvailable();
    if (use_native_bridge) {
      ScopedUtfChars isa_string(env, instructionSet);
      use_native_bridge = android::NeedsNativeBridge(isa_string.c_str());
    }
    if (use_native_bridge && dataDir == NULL) {
      // dataDir should never be null if we need to use a native bridge.
      // In general, dataDir will never be null for normal applications. It can only happen in
      // special cases (for isolated processes which are not associated with any app). These are
      // launched by the framework and should not be emulated anyway.
      use_native_bridge = false;
      ALOGW("Native bridge will not be used because dataDir == NULL.");
    }

    if (!MountEmulatedStorage(uid, mount_external, use_native_bridge)) { // mount命名空间
      ALOGW("Failed to mount emulated storage: %s", strerror(errno));
      if (errno == ENOTCONN || errno == EROFS) {
        // When device is actively encrypting, we get ENOTCONN here
        // since FUSE was mounted before the framework restarted.
        // When encrypted device is booting, we get EROFS since
        // FUSE hasn't been created yet by init.
        // In either case, continue without external storage.
      } else {
        RuntimeAbort(env, __LINE__, "Cannot continue without emulated storage");
      }
    }

    if (!is_system_server) {
        int rc = createProcessGroup(uid, getpid()); // 对于非system_server子进程,则创建进程组
        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); // 设置资源limit // javaRlimits等于null,不限制

    if (use_native_bridge) {
      ScopedUtfChars isa_string(env, instructionSet);
      ScopedUtfChars data_dir(env, dataDir);
      android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());
    }

    int rc = setresgid(gid, gid, gid); // 分别设置真实的,有效的和保存过的组标识号
    if (rc == -1) {
      ALOGE("setresgid(%d) failed: %s", gid, strerror(errno));
      RuntimeAbort(env, __LINE__, "setresgid failed");
    }

    rc = setresuid(uid, uid, uid); // 分别设置真实的,有效的和保存过的用户标识号
    if (rc == -1) {
      ALOGE("setresuid(%d) failed: %s", uid, strerror(errno));
      RuntimeAbort(env, __LINE__, "setresuid failed");
    }

    if (NeedsNoRandomizeWorkaround()) {
        // Work around ARM kernel ASLR lossage (http://b/5817320).
        int old_personality = personality(0xffffffff);
        int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
        if (new_personality == -1) {
            ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
        }
    }

    SetCapabilities(env, permittedCapabilities, effectiveCapabilities); // 配置新的Capabilities权限

    SetSchedulerPolicy(env); // 设置调度策略

    const char* se_info_c_str = NULL;
    ScopedUtfChars* se_info = NULL;
    if (java_se_info != NULL) {
        se_info = new ScopedUtfChars(env, java_se_info);
        se_info_c_str = se_info->c_str();
        if (se_info_c_str == NULL) {
          RuntimeAbort(env, __LINE__, "se_info_c_str == NULL");
        }
    }
    const char* se_name_c_str = NULL;
    ScopedUtfChars* se_name = NULL;
    if (java_se_name != NULL) {
        se_name = new ScopedUtfChars(env, java_se_name);
        se_name_c_str = se_name->c_str();
        if (se_name_c_str == NULL) {
          RuntimeAbort(env, __LINE__, "se_name_c_str == NULL");
        }
    }
    rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str); // 设置SELinux的domain上下文
    if (rc == -1) {
      ALOGE("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
            is_system_server, se_info_c_str, se_name_c_str);
      RuntimeAbort(env, __LINE__, "selinux_android_setcontext failed");
    }

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

    delete se_info;
    delete se_name;

    UnsetSigChldHandler(); // 将子进程system_server的SIGCHLD信号的处理函数修改回系统默认函数

    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
                              is_system_server, instructionSet); // 调用zygote.callPostForkChildHooks()方法 // 完成一些运行时的后期工作
    if (env->ExceptionCheck()) {
      RuntimeAbort(env, __LINE__, "Error calling post fork hooks.");
    }
  } else if (pid > 0) { // 进入父进程,即zygote64进程
    // the parent process

#ifdef ENABLE_SCHED_BOOST
    // unset scheduler knob
    SetForkLoad(false);
#endif

  }
  return pid;
}



2.3 SetSigChldHandler

static void SetSigChldHandler() {
  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = SigChldHandler;

  int err = sigaction(SIGCHLD, &sa, NULL);  // 设置信号处理函数,SIGCHLD是子进程终止的信号
  if (err < 0) {
    ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
  }
}

static void SigChldHandler(int /*signal_number*/) {
  pid_t pid;
  int status;

  // It's necessary to save and restore the errno during this function.
  // Since errno is stored per thread, changing it here modifies the errno
  // on the thread on which this signal handler executes. If a signal occurs
  // between a call and an errno check, it's possible to get the errno set
  // here.
  // See b/23572286 for extra information.
  int saved_errno = errno;

  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { // 等待任何子进程
     // Log process-death status that we care about.  In general it is
     // not safe to call LOG(...) from a signal handler because of
     // possible reentrancy.  However, we know a priori that the
     // current implementation of LOG() is safe to call from a SIGCHLD
     // handler in the zygote process.  If the LOG() implementation
     // changes its locking strategy or its use of syscalls within the
     // lazy-init critical section, its use here may become unsafe.
    if (WIFEXITED(status)) {
      if (WEXITSTATUS(status)) {
        ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
      }
    } else if (WIFSIGNALED(status)) {
      if (WTERMSIG(status) != SIGKILL) {
        ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
      }
      if (WCOREDUMP(status)) {
        ALOGI("Process %d dumped core.", pid);
      }
    }

    // If the just-crashed process is the system_server, bring down zygote
    // so that it is restarted by init and system server will be restarted
    // from there.
    if (pid == gSystemServerPid) { // 当system_server退出时
      ALOGE("Exit zygote because system server (%d) has terminated", pid);
      kill(getpid(), SIGKILL); // zygote64杀死自己,init将会重启zygote64
    }
  }

  // Note that we shouldn't consider ECHILD an error because
  // the secondary zygote might have no children left to wait for.
  if (pid < 0 && errno != ECHILD) {
    ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
  }

  errno = saved_errno;
}



三 handleSystemServerProcess

3.0 handleSystemServerProcess

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

    closeServerSocket(); // 关闭从父进程zygote64复制而来的Socket

    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO); // 设置system_server新建文件时预设的权限掩码 

    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName); // 设置当前进程名为system_server
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); // SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar
    if (systemServerClasspath != null) {
        performSystemServerDexOpt(systemServerClasspath); // 进行dexopt优化
    }

    if (parsedArgs.invokeWith != null) { // system_server进程invokeWith为null
        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 = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); // 创建类加载器
            Thread.currentThread().setContextClassLoader(cl); // 设置当前线程(system_server)的类加载器
        }

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

    /* should never reach here */
}

3.1 performSystemServerDexOpt

private static void performSystemServerDexOpt(String classPath) {
    final String[] classPathElements = classPath.split(":");
    final InstallerConnection installer = new InstallerConnection();  // 创建一个InstallerConnection
    installer.waitForConnection();  // 连接installd服务端Socket
    final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();

    try {
        for (String classPathElement : classPathElements) {
            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*/); // 进行dexopt优化
            }
        }
    } catch (IOException ioe) {
        throw new RuntimeException("Error starting system_server", ioe);
    } finally {
        installer.disconnect();  // 断开与installd服务端Socket连接
    }
}

四 zygoteInit

4.0 zygoteInit

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");  // 开始Systrace追踪RuntimeInit
    redirectLogStreams();  // 重定向log输出

    commonInit();  // 进行一些通用的初始化
    nativeZygoteInit();
    applicationInit(targetSdkVersion, argv, classLoader);
}

4.1 commonInit

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"); // persist.sys.timezone=Asia/Shanghai
        }
    });
    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(); // 重置log设置
    new AndroidConfig(); // 设置Android log

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

    /*
     * 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;
}

4.2 com_android_internal_os_RuntimeInit_nativeZygoteInit

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

virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self(); // 构造进程的ProcessState对象
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool(); // 启动线程池
}

4.3 applicationInit

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); // 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);  // 停止Systrace追踪RuntimeInit

    // Remaining arguments are passed to the start class's static main
    invokeStaticMain(args.startClass, args.startArgs, classLoader); // 调用com.android.server.SystemServer类的main函数
}

五 invokeStaticMain

5.0 invokeStaticMain

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

    try {
        cl = Class.forName(className, true, classLoader); // 装载com.android.server.SystemServer类,并对其进行初始化
    } 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 }); // 获取com.android.server.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))) { // Java规范定义了main函数的声明必须是 public static void main(String args[])
        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); // 抛出MethodAndArgsCaller异常
}


5.1 MethodAndArgsCaller

回到frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 的main函数
public static void main(String argv[]) {
    try {

    ...

        if (startSystemServer) {
            startSystemServer(abiList, socketName); // 启动system_server进程
        }

        Log.i(TAG, "Accepting command socket connections");
        runSelectLoop(abiList);

        closeServerSocket();
    } catch (MethodAndArgsCaller caller) { // 捕获MethodAndArgsCaller异常
        caller.run(); // 调用MethodAndArgsCaller的run方法
    } catch (RuntimeException ex) {
        Log.e(TAG, "Zygote died with exception", ex);
        closeServerSocket();
        throw ex;
    }


5.2 MethodAndArgsCaller.run

MethodAndArgsCaller是一个异常类
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; // com.android.server.SystemServer类的main方法
        mArgs = args; // 传递给SystemServer类main方法的参数
    }

    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs }); // 调用com.android.server.SystemServer类的main方法
        } 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);
        }
    }



0 0