Android System Server进程源码分析 上

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

    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/ffmxnjm/article/details/70665372
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞