当前位置:   article > 正文

Android FrameWork(二)SystemServer(上)_forkandspecializecommon

forkandspecializecommon

    上次在写init和zygote的时候,说起过,SystemServer是Android系统的系统服务模块,主要功能是管理Android的system service。system_server进程是zygote进程通过fork方法创造出来的第一个子进程,而且当system_server进程启动失败时会导致zygote进程自杀重启。今天,看一下SystemServer的启动过程。

一.ZygoteInit.forkSystemServer

    上次说到,ZygoteInit类通过main方法中如下代码启动SystemServer的:

  1. if (startSystemServer) {
  2. Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
  3. // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
  4. // child (system_server) process.
  5. if (r != null) {
  6. r.run();
  7. return;
  8. }
  9. }

    接下来,我们看一下forkSystemServer方法的具体实现,源码如下:

  1. /**
  2. * Prepare the arguments and forks for the system server process.
  3. *
  4. * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
  5. * child process, and {@code null} in the parent.
  6. */
  7. private static Runnable forkSystemServer(String abiList, String socketName,
  8. ZygoteServer zygoteServer) {
  9. long capabilities = posixCapabilitiesAsBits(
  10. OsConstants.CAP_IPC_LOCK,
  11. OsConstants.CAP_KILL,
  12. OsConstants.CAP_NET_ADMIN,
  13. OsConstants.CAP_NET_BIND_SERVICE,
  14. OsConstants.CAP_NET_BROADCAST,
  15. OsConstants.CAP_NET_RAW,
  16. OsConstants.CAP_SYS_MODULE,
  17. OsConstants.CAP_SYS_NICE,
  18. OsConstants.CAP_SYS_PTRACE,
  19. OsConstants.CAP_SYS_TIME,
  20. OsConstants.CAP_SYS_TTY_CONFIG,
  21. OsConstants.CAP_WAKE_ALARM,
  22. OsConstants.CAP_BLOCK_SUSPEND
  23. );
  24. /* Containers run without some capabilities, so drop any caps that are not available. */
  25. StructCapUserHeader header = new StructCapUserHeader(
  26. OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
  27. StructCapUserData[] data;
  28. try {
  29. data = Os.capget(header);
  30. } catch (ErrnoException ex) {
  31. throw new RuntimeException("Failed to capget()", ex);
  32. }
  33. capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
  34. /* Hardcoded command line to start the system server */
  35. String args[] = {
  36. "--setuid=1000",
  37. "--setgid=1000",
  38. "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
  39. "--capabilities=" + capabilities + "," + capabilities,
  40. "--nice-name=system_server",
  41. "--runtime-args",
  42. "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
  43. "com.android.server.SystemServer",
  44. };
  45. ZygoteConnection.Arguments parsedArgs = null;
  46. int pid;
  47. try {
  48. parsedArgs = new ZygoteConnection.Arguments(args);
  49. ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
  50. ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
  51. boolean profileSystemServer = SystemProperties.getBoolean(
  52. "dalvik.vm.profilesystemserver", false);
  53. if (profileSystemServer) {
  54. parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
  55. }
  56. /* Request to fork the system server process */
  57. pid = Zygote.forkSystemServer(
  58. parsedArgs.uid, parsedArgs.gid,
  59. parsedArgs.gids,
  60. parsedArgs.runtimeFlags,
  61. null,
  62. parsedArgs.permittedCapabilities,
  63. parsedArgs.effectiveCapabilities);
  64. } catch (IllegalArgumentException ex) {
  65. throw new RuntimeException(ex);
  66. }
  67. /* For child process */
  68. if (pid == 0) {
  69. if (hasSecondZygote(abiList)) {
  70. waitForSecondaryZygote(socketName);
  71. }
  72. zygoteServer.closeServerSocket();
  73. return handleSystemServerProcess(parsedArgs);
  74. }
  75. return null;
  76. }

     我们把方法前的英文注释翻译一下:为system server进程准备参数和forks。在子进程中返回一个提供进入system server代码入口点的Runnable并且在父进程中返回null。

    在这里引申一下,我么经常说fork一个进程。那么,什么是fork?fork是一个分叉函数,一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程。fork函数被调用一次但返回两次,两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。

    forkSystemServer方法的主要工作流程是:

    (1)获取POSIX(可移植操作系统接口)功能列表的相关位数:posixCapabilitiesAsBits

    (2)放弃一些容器运行时不可用的功能:逻辑运算符&和|

    (3)硬编码命令行启动system server

    (4)发送fork一个system server 子进程的请求:Zygote.forkSystemServer

    (5)如果pid是0,说明system server启动成功。关闭socket,并且做一些启动system server剩余的工作:handleSystemServerProcess(parsedArgs)

二.Zygote.forkSystemServer

    上面ZygoteInit.forkSystemServer方法代码中,调用了Zygote.forkSystemServer方法,我们看一下源码:

  1. /**
  2. * Special method to start the system server process. In addition to the
  3. * common actions performed in forkAndSpecialize, the pid of the child
  4. * process is recorded such that the death of the child process will cause
  5. * zygote to exit.
  6. *
  7. * @param uid the UNIX uid that the new process should setuid() to after
  8. * fork()ing and and before spawning any threads.
  9. * @param gid the UNIX gid that the new process should setgid() to after
  10. * fork()ing and and before spawning any threads.
  11. * @param gids null-ok; a list of UNIX gids that the new process should
  12. * setgroups() to after fork and before spawning any threads.
  13. * @param runtimeFlags bit flags that enable ART features.
  14. * @param rlimits null-ok an array of rlimit tuples, with the second
  15. * dimension having a length of 3 and representing
  16. * (resource, rlim_cur, rlim_max). These are set via the posix
  17. * setrlimit(2) call.
  18. * @param permittedCapabilities argument for setcap()
  19. * @param effectiveCapabilities argument for setcap()
  20. *
  21. * @return 0 if this is the child, pid of the child
  22. * if this is the parent, or -1 on error.
  23. */
  24. public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
  25. int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
  26. VM_HOOKS.preFork();
  27. // Resets nice priority for zygote process.
  28. resetNicePriority();
  29. int pid = nativeForkSystemServer(
  30. uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
  31. // Enable tracing as soon as we enter the system_server.
  32. if (pid == 0) {
  33. Trace.setTracingEnabled(true, runtimeFlags);
  34. }
  35. VM_HOOKS.postForkCommon();
  36. return pid;
  37. }
  38. native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
  39. int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

    我们还是看一下方法的注释:创建system server的特殊方法。除了在forkandspecialize方法中执行的常见操作外,还记录了子进程的PID,以便子进程消亡的时候让zygote进程退出。这个方法最后调用了一个native方法:nativeForkSystemServer。

三.nativeForkSystemServer

    native方法的实现,都是在cpp文件中,路径是:/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp。看一下这个方法的源码:

  1. static jint com_android_internal_os_Zygote_nativeForkSystemServer(
  2. JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
  3. jint runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
  4. jlong effectiveCapabilities) {
  5. pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
  6. runtime_flags, rlimits,
  7. permittedCapabilities, effectiveCapabilities,
  8. MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
  9. NULL, false, NULL, NULL);
  10. if (pid > 0) {
  11. // The zygote process checks whether the child process has died or not.
  12. ALOGI("System server process %d has been created", pid);
  13. gSystemServerPid = pid;
  14. // There is a slight window that the system server process has crashed
  15. // but it went unnoticed because we haven't published its pid yet. So
  16. // we recheck here just to make sure that all is well.
  17. int status;
  18. if (waitpid(pid, &status, WNOHANG) == pid) {
  19. ALOGE("System server process %d has died. Restarting Zygote!", pid);
  20. RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
  21. }
  22. // Assign system_server to the correct memory cgroup.
  23. // Not all devices mount /dev/memcg so check for the file first
  24. // to avoid unnecessarily printing errors and denials in the logs.
  25. if (!access("/dev/memcg/system/tasks", F_OK) &&
  26. !WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) {
  27. ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid);
  28. }
  29. }
  30. return pid;
  31. }

 四.ForkAndSpecializeCommon

    这是一个非常长的方法,我们可以看到代码分为两个逻辑,一个是if(pid ==0),另一个是if(pid>0)。前面我们说到过,fork进程成功后,返回两次,子进程返回0,父进程返回子进程的id。到此system_server进程已完成了创建的所有工作。

  1. // Utility routine to fork zygote and specialize the child process.
  2. static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
  3. jint runtime_flags, jobjectArray javaRlimits,
  4. jlong permittedCapabilities, jlong effectiveCapabilities,
  5. jint mount_external,
  6. jstring java_se_info, jstring java_se_name,
  7. bool is_system_server, jintArray fdsToClose,
  8. jintArray fdsToIgnore, bool is_child_zygote,
  9. jstring instructionSet, jstring dataDir) {
  10. SetSignalHandlers();
  11. sigset_t sigchld;
  12. sigemptyset(&sigchld);
  13. sigaddset(&sigchld, SIGCHLD);
  14. auto fail_fn = [env, java_se_name, is_system_server](const std::string& msg)
  15. __attribute__ ((noreturn)) {
  16. const char* se_name_c_str = nullptr;
  17. std::unique_ptr<ScopedUtfChars> se_name;
  18. if (java_se_name != nullptr) {
  19. se_name.reset(new ScopedUtfChars(env, java_se_name));
  20. se_name_c_str = se_name->c_str();
  21. }
  22. if (se_name_c_str == nullptr && is_system_server) {
  23. se_name_c_str = "system_server";
  24. }
  25. const std::string& error_msg = (se_name_c_str == nullptr)
  26. ? msg
  27. : StringPrintf("(%s) %s", se_name_c_str, msg.c_str());
  28. env->FatalError(error_msg.c_str());
  29. __builtin_unreachable();
  30. };
  31. // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
  32. // log, which would result in the logging FDs we close being reopened.
  33. // This would cause failures because the FDs are not whitelisted.
  34. //
  35. // Note that the zygote process is single threaded at this point.
  36. if (sigprocmask(SIG_BLOCK, &sigchld, nullptr) == -1) {
  37. fail_fn(CREATE_ERROR("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)));
  38. }
  39. // Close any logging related FDs before we start evaluating the list of
  40. // file descriptors.
  41. __android_log_close();
  42. std::string error_msg;
  43. // If this is the first fork for this zygote, create the open FD table.
  44. // If it isn't, we just need to check whether the list of open files has
  45. // changed (and it shouldn't in the normal case).
  46. std::vector<int> fds_to_ignore;
  47. if (!FillFileDescriptorVector(env, fdsToIgnore, &fds_to_ignore, &error_msg)) {
  48. fail_fn(error_msg);
  49. }
  50. if (gOpenFdTable == NULL) {
  51. gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, &error_msg);
  52. if (gOpenFdTable == NULL) {
  53. fail_fn(error_msg);
  54. }
  55. } else if (!gOpenFdTable->Restat(fds_to_ignore, &error_msg)) {
  56. fail_fn(error_msg);
  57. }
  58. pid_t pid = fork();
  59. if (pid == 0) {
  60. PreApplicationInit();
  61. // Clean up any descriptors which must be closed immediately
  62. if (!DetachDescriptors(env, fdsToClose, &error_msg)) {
  63. fail_fn(error_msg);
  64. }
  65. // Re-open all remaining open file descriptors so that they aren't shared
  66. // with the zygote across a fork.
  67. if (!gOpenFdTable->ReopenOrDetach(&error_msg)) {
  68. fail_fn(error_msg);
  69. }
  70. if (sigprocmask(SIG_UNBLOCK, &sigchld, nullptr) == -1) {
  71. fail_fn(CREATE_ERROR("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)));
  72. }
  73. // Keep capabilities across UID change, unless we're staying root.
  74. if (uid != 0) {
  75. if (!EnableKeepCapabilities(&error_msg)) {
  76. fail_fn(error_msg);
  77. }
  78. }
  79. if (!SetInheritable(permittedCapabilities, &error_msg)) {
  80. fail_fn(error_msg);
  81. }
  82. if (!DropCapabilitiesBoundingSet(&error_msg)) {
  83. fail_fn(error_msg);
  84. }
  85. bool use_native_bridge = !is_system_server && (instructionSet != NULL)
  86. && android::NativeBridgeAvailable();
  87. if (use_native_bridge) {
  88. ScopedUtfChars isa_string(env, instructionSet);
  89. use_native_bridge = android::NeedsNativeBridge(isa_string.c_str());
  90. }
  91. if (use_native_bridge && dataDir == NULL) {
  92. // dataDir should never be null if we need to use a native bridge.
  93. // In general, dataDir will never be null for normal applications. It can only happen in
  94. // special cases (for isolated processes which are not associated with any app). These are
  95. // launched by the framework and should not be emulated anyway.
  96. use_native_bridge = false;
  97. ALOGW("Native bridge will not be used because dataDir == NULL.");
  98. }
  99. if (!MountEmulatedStorage(uid, mount_external, use_native_bridge, &error_msg)) {
  100. ALOGW("Failed to mount emulated storage: %s (%s)", error_msg.c_str(), strerror(errno));
  101. if (errno == ENOTCONN || errno == EROFS) {
  102. // When device is actively encrypting, we get ENOTCONN here
  103. // since FUSE was mounted before the framework restarted.
  104. // When encrypted device is booting, we get EROFS since
  105. // FUSE hasn't been created yet by init.
  106. // In either case, continue without external storage.
  107. } else {
  108. fail_fn(error_msg);
  109. }
  110. }
  111. // If this zygote isn't root, it won't be able to create a process group,
  112. // since the directory is owned by root.
  113. if (!is_system_server && getuid() == 0) {
  114. int rc = createProcessGroup(uid, getpid());
  115. if (rc != 0) {
  116. if (rc == -EROFS) {
  117. ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
  118. } else {
  119. ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));
  120. }
  121. }
  122. }
  123. std::string error_msg;
  124. if (!SetGids(env, javaGids, &error_msg)) {
  125. fail_fn(error_msg);
  126. }
  127. if (!SetRLimits(env, javaRlimits, &error_msg)) {
  128. fail_fn(error_msg);
  129. }
  130. if (use_native_bridge) {
  131. ScopedUtfChars isa_string(env, instructionSet);
  132. ScopedUtfChars data_dir(env, dataDir);
  133. android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());
  134. }
  135. int rc = setresgid(gid, gid, gid);
  136. if (rc == -1) {
  137. fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));
  138. }
  139. // Must be called when the new process still has CAP_SYS_ADMIN, in this case, before changing
  140. // uid from 0, which clears capabilities. The other alternative is to call
  141. // prctl(PR_SET_NO_NEW_PRIVS, 1) afterward, but that breaks SELinux domain transition (see
  142. // b/71859146). As the result, privileged syscalls used below still need to be accessible in
  143. // app process.
  144. SetUpSeccompFilter(uid);
  145. rc = setresuid(uid, uid, uid);
  146. if (rc == -1) {
  147. fail_fn(CREATE_ERROR("setresuid(%d) failed: %s", uid, strerror(errno)));
  148. }
  149. if (NeedsNoRandomizeWorkaround()) {
  150. // Work around ARM kernel ASLR lossage (http://b/5817320).
  151. int old_personality = personality(0xffffffff);
  152. int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
  153. if (new_personality == -1) {
  154. ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));
  155. }
  156. }
  157. if (!SetCapabilities(permittedCapabilities, effectiveCapabilities, permittedCapabilities,
  158. &error_msg)) {
  159. fail_fn(error_msg);
  160. }
  161. if (!SetSchedulerPolicy(&error_msg)) {
  162. fail_fn(error_msg);
  163. }
  164. const char* se_info_c_str = NULL;
  165. ScopedUtfChars* se_info = NULL;
  166. if (java_se_info != NULL) {
  167. se_info = new ScopedUtfChars(env, java_se_info);
  168. se_info_c_str = se_info->c_str();
  169. if (se_info_c_str == NULL) {
  170. fail_fn("se_info_c_str == NULL");
  171. }
  172. }
  173. const char* se_name_c_str = NULL;
  174. ScopedUtfChars* se_name = NULL;
  175. if (java_se_name != NULL) {
  176. se_name = new ScopedUtfChars(env, java_se_name);
  177. se_name_c_str = se_name->c_str();
  178. if (se_name_c_str == NULL) {
  179. fail_fn("se_name_c_str == NULL");
  180. }
  181. }
  182. rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
  183. if (rc == -1) {
  184. fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
  185. is_system_server, se_info_c_str, se_name_c_str));
  186. }
  187. // Make it easier to debug audit logs by setting the main thread's name to the
  188. // nice name rather than "app_process".
  189. if (se_name_c_str == NULL && is_system_server) {
  190. se_name_c_str = "system_server";
  191. }
  192. if (se_name_c_str != NULL) {
  193. SetThreadName(se_name_c_str);
  194. }
  195. delete se_info;
  196. delete se_name;
  197. // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers).
  198. UnsetChldSignalHandler();
  199. env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
  200. is_system_server, is_child_zygote, instructionSet);
  201. if (env->ExceptionCheck()) {
  202. fail_fn("Error calling post fork hooks.");
  203. }
  204. } else if (pid > 0) {
  205. // the parent process
  206. // We blocked SIGCHLD prior to a fork, we unblock it here.
  207. if (sigprocmask(SIG_UNBLOCK, &sigchld, nullptr) == -1) {
  208. fail_fn(CREATE_ERROR("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)));
  209. }
  210. }
  211. return pid;
  212. }

五.handleSystemServerProcess

    上面说到,system server启动成功后,需要做一些剩余的工作。通过上面的流程,system server已经启动成功。剩余的工作就在handleSystemServerProcess(parsedArgs)方法中执行。下面是handleSystemServerProcess的源码:

  1. /**
  2. * Finish remaining work for the newly forked system server process.
  3. */
  4. private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
  5. // set umask to 0077 so new files and directories will default to owner-only permissions.
  6. Os.umask(S_IRWXG | S_IRWXO);
  7. if (parsedArgs.niceName != null) {
  8. Process.setArgV0(parsedArgs.niceName);
  9. }
  10. final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
  11. if (systemServerClasspath != null) {
  12. performSystemServerDexOpt(systemServerClasspath);
  13. // Capturing profiles is only supported for debug or eng builds since selinux normally
  14. // prevents it.
  15. boolean profileSystemServer = SystemProperties.getBoolean(
  16. "dalvik.vm.profilesystemserver", false);
  17. if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
  18. try {
  19. prepareSystemServerProfile(systemServerClasspath);
  20. } catch (Exception e) {
  21. Log.wtf(TAG, "Failed to set up system server profile", e);
  22. }
  23. }
  24. }
  25. if (parsedArgs.invokeWith != null) {
  26. String[] args = parsedArgs.remainingArgs;
  27. // If we have a non-null system server class path, we'll have to duplicate the
  28. // existing arguments and append the classpath to it. ART will handle the classpath
  29. // correctly when we exec a new process.
  30. if (systemServerClasspath != null) {
  31. String[] amendedArgs = new String[args.length + 2];
  32. amendedArgs[0] = "-cp";
  33. amendedArgs[1] = systemServerClasspath;
  34. System.arraycopy(args, 0, amendedArgs, 2, args.length);
  35. args = amendedArgs;
  36. }
  37. WrapperInit.execApplication(parsedArgs.invokeWith,
  38. parsedArgs.niceName, parsedArgs.targetSdkVersion,
  39. VMRuntime.getCurrentInstructionSet(), null, args);
  40. throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
  41. } else {
  42. ClassLoader cl = null;
  43. if (systemServerClasspath != null) {
  44. cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
  45. Thread.currentThread().setContextClassLoader(cl);
  46. }
  47. /*
  48. * Pass the remaining arguments to SystemServer.
  49. */
  50. return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
  51. }
  52. /* should never reach here */
  53. }

    那么,这个方法做了什么工作呢?接下来,我们看一下这个方法的流程:

    (1)设置系统的umask值。什么是umask?当我们登录系统之后创建一个文件总是有一个默认权限的,umask就是用来设置用户创建文件的默认权限。

    (2)准备system server的配置文件。selinux通常不支持获取配置文件,因此,只能在debug或者eng版本获取。

    (3)传递剩余的参数给system server。通过ZygoteInit.zygoteInit()方法。

六.zygoteInit

    在handleSystemServerProcess最后一步工作中,通过ZygoteInit.zygoteInit方法传递剩余的参数给system server。那么zygoteInit究竟做了什么?我们先把源码贴出来:

  1. public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
  2. if (RuntimeInit.DEBUG) {
  3. Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
  4. }
  5. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
  6. RuntimeInit.redirectLogStreams();
  7. RuntimeInit.commonInit();
  8. ZygoteInit.nativeZygoteInit();
  9. return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
  10. }

    zygoteInit主要做了三个工作:

    (1)commonInit():通用的初始化工作。这个我们不细看。

    (2)nativeZygoteInit():native的方法,涉及到zygote的初始化。

    (3)RuntimeInit.applicationInit():这是最后的返回值,我们继续跟踪一下applicationInit方法。

七.applicationInit

    applicationInit方法在RuntimeInit类中,路径是:/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java。我们先看一下applicationInit的源码:

  1. protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
  2. ClassLoader classLoader) {
  3. // If the application calls System.exit(), terminate the process
  4. // immediately without running any shutdown hooks. It is not possible to
  5. // shutdown an Android application gracefully. Among other things, the
  6. // Android runtime shutdown hooks close the Binder driver, which can cause
  7. // leftover running threads to crash before the process actually exits.
  8. nativeSetExitWithoutCleanup(true);
  9. // We want to be fairly aggressive about heap utilization, to avoid
  10. // holding on to a lot of memory that isn't needed.
  11. VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
  12. VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
  13. final Arguments args = new Arguments(argv);
  14. // The end of of the RuntimeInit event (see #zygoteInit).
  15. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  16. // Remaining arguments are passed to the start class's static main
  17. return findStaticMain(args.startClass, args.startArgs, classLoader);
  18. }

    最后,通过findStaticMain方法传递剩余的参数给类的static main方法。到底是哪个类的static main方法呢?我们继续追踪源码。

八.findStaticMain

  1. protected static Runnable findStaticMain(String className, String[] argv,
  2. ClassLoader classLoader) {
  3. Class<?> cl;
  4. try {
  5. cl = Class.forName(className, true, classLoader);
  6. } catch (ClassNotFoundException ex) {
  7. throw new RuntimeException(
  8. "Missing class when invoking static main " + className,
  9. ex);
  10. }
  11. Method m;
  12. try {
  13. m = cl.getMethod("main", new Class[] { String[].class });
  14. } catch (NoSuchMethodException ex) {
  15. throw new RuntimeException(
  16. "Missing static main on " + className, ex);
  17. } catch (SecurityException ex) {
  18. throw new RuntimeException(
  19. "Problem getting static main on " + className, ex);
  20. }
  21. int modifiers = m.getModifiers();
  22. if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
  23. throw new RuntimeException(
  24. "Main method is not public and static on " + className);
  25. }
  26. /*
  27. * This throw gets caught in ZygoteInit.main(), which responds
  28. * by invoking the exception's run() method. This arrangement
  29. * clears up all the stack frames that were required in setting
  30. * up the process.
  31. */
  32. return new MethodAndArgsCaller(m, argv);
  33. }

    在return语句上面有一段注释,意思是:这个会在ZygoteInit.main方法被捕获,他通过调用异常的run方法来响应。也就是findStaticMain()方法中抛出的异常MethodAndArgsCaller,从而进入caller.run()方法。下面是MethodAndArgsCaller的源码:

  1. static class MethodAndArgsCaller implements Runnable {
  2. /** method to call */
  3. private final Method mMethod;
  4. /** argument array */
  5. private final String[] mArgs;
  6. public MethodAndArgsCaller(Method method, String[] args) {
  7. mMethod = method;
  8. mArgs = args;
  9. }
  10. public void run() {
  11. try {
  12. mMethod.invoke(null, new Object[] { mArgs });
  13. } catch (IllegalAccessException ex) {
  14. throw new RuntimeException(ex);
  15. } catch (InvocationTargetException ex) {
  16. Throwable cause = ex.getCause();
  17. if (cause instanceof RuntimeException) {
  18. throw (RuntimeException) cause;
  19. } else if (cause instanceof Error) {
  20. throw (Error) cause;
  21. }
  22. throw new RuntimeException(ex);
  23. }
  24. }
  25. }

    通过如上代码,我们可以看出,通过反射的方式,进入SystemServer的main方法。为什么要通过抛出异常的方式进入main方法呢?因为从ZygoteInit的main开始fork一个进程出来,经过了层层调用,系统中累积了不少栈帧,为了一个创建一个干干净净的进程,需要清除里面的栈帧,故抛出这个异常。

    接下来,我画个简单的图总结一下system server的启动流程,其中第一行加粗的是类,第二行是方法,启动流程大致如下:

    最后,简单总结一下。今天把system Server启动的过程给总结了一下。其实,前面还算顺利,到了最后,通过抛出异常和反射进入System server的main方法这一块确实一开始没看明白。后来,结合代码的注释,以及查询相关资料,了解了这样做的用意。下次博客,继续跟踪一下SystemServer的main方法。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号