深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解
深入学习 Android Framework
第三:深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解
文章目录
- 深入学习 Android Framework
- 前言
- 一、Android 系统的启动流程
- 1. 流程图
- 2. 启动流程概述
- 二、源码详解
- 1. 时序图
- 2. 源代码
- 1、ZygoteInit # main()
- 2、ZygoteInit # forkSystemServer()
- 2.1、Zygote # forkSystemServer()
- 2.1.1、Zygote # nativeForkSystemServer()
- 2.1.2、Zygote # ForkCommon()
- 2.1.3、Zygote # SpecializeCommon()
- 2.2、ZygoteInit # handleSystemServerProcess()
- 2.3 ZygoteInit # zygoteInit()
- 2.3.1 ZygoteInit # nativeZygoteInit()
- 2.3.2 app_main # main()
- 2.3.3 RuntimeInit # applicationInit()
- 2.3.4 RuntimeInit # findStaticMain()
- 2.3.5 MethodAndArgsCaller # run()
- 3 SystemServer # main()
- 3.1 SystemServer # performPendingShutdown()
- 3.2 SystemServer # createSystemContext()
- 3.3 SystemServiceManager
- 3.4 SystemServer # startBootstrapServices()
- 3.5 SystemServer # startCoreServices()
- 3.5 SystemServer # startOtherServices()
- 三、SystemServer 启动的服务及其作用
- 1、引导服务
- 2、核心服务
- 3、其他服务
- 总结
前言
Zygote 的纸面意思 “受精卵”,由他孵化出 Android 系统的其他进程。SystemServer 和其他所有 Dalivik 虚拟机进程都是由 Zygote 经过 fork 复制而来。SystemServer 作为 Zygote 进程 fork 出的第一个进程,其进程名为:system_server。其承载着整个 Framework 的核心服务,如创建并启动 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService、InputManagerService 等 90 多个核心系统服务。接下来一起深入学习一下 SystemServer 进程的创建与启动流程。
一、Android 系统的启动流程
1. 流程图

2. 启动流程概述
结合上面的流程图,先概述一下 Android 系统的总体启动流程:
- Android 系统按下电源键开机时,系统的引导芯片代码将从预定义的地方 ( 在ROM ) 开始执行,并去加载引导程序 BootLoader 到 RAM 中,然后执行 BootLoader。
- 引导程序是 Android 系统被拉起来之前的一个程序,其作用是把 Android 系统拉起运行,也就是把 Linux 内核启动起来。
- 当 Linux 内核启动后会初始化各种软硬件环境、加载驱动程序、挂载根文件系统等,待到加载工作准备完毕后,开始加载一些特定的程序(进程),第一个加载的是 init 进程,init 进程是 Linux 系统中用户空间的第一个进程,进程号固定位 1。
- 内核启动后,在用户空间启动 init 进程,并调用 init 的 main() 方法。其作用有:创建目录、挂载分区;解析 init.rc 配置文件;启动解析 init.rc 配置文件获取到的服务(如:Zygote进程、ServiceManager等);守护解析后启动的服务;
- 创建启动 Zygote 进程,首先会创建一个 Java 虚拟机实例,然后注册所有 Framework 相关的系统 JNI 接口,为 Java 世界做好准备。通过 JNI 调用进入 Java 世界,并调用 ZygoteInit.main() 方法,给 Zygote 注册 Socket 用于进程间通信,同时预加载一些常用的 Java 类库和系统资源(如:system/etc/preloaded-c]asses 文件中的类、drawable和 color 资源、opengl 等),执行 gc() 清理内存,为 fork 子进程做好准备。然后 fork 出子进程,并在子进程中初始化 SystemServer 进程,初始化的过程中启动 Android 系统所有的 Service 服务(其中包括输入系统服务 IMS);
- Zygote 进程启动后,在后台持续监听 Socket 等待新的应用启动请求,并且监听 SystemServer 的 SIGHID 信号,如果 SystemServer 挂掉,立即 kill 掉 Zygote 自己,然后 init 会重启 Zygote,再启动 SystemServer,使系统恢复正常(如果不能重新起来,将会导致手机重启)。
- 当ActivityManagerService 以后简称 AMS 执行 startService() 启动服务,并调用其 systemReady() 方法后,寻找系统的 “Startup” Application,并向 Zygote 发送请求,Zygote fork 出 “Startup” Application,也就是启动 Launcher 应用,然后将已经安装的应用程序图标显示到桌面上,完成 Android 系统启动。
二、源码详解
接下来,就让我们深入 Android 系统源码,通过源码来详细的分析学习 SystemServer 的启动流程。首先看一下 SystemServer 进程启动的时序图,即先总览全局,再深入细节,便于理解代码。
1. 时序图

2. 源代码
在分析 Zygote 进程启动流程中可知, system_server 进程是在 ZygoteInit # main() 函数进入循环等待之前启动的,进入代码一探究竟
1、ZygoteInit # main()
xref: /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {......@UnsupportedAppUsagepublic static void main(String[] argv) {ZygoteServer zygoteServer = null;......Runnable caller;try {...... // 解析传入参数zygoteServer = new ZygoteServer(isPrimaryZygote);if (startSystemServer) {// fork 出 system_server 进程Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);// {@code r == null} in the parent (zygote) process, and {@code r != null} in the// child (system_server) process.// 如果返回值 r 为空则是在父进程,即 Zygote 进程,如果 r 不为空则是在子进程,即 system_server 进程if (r != null) {r.run(); // 启动 SystemServer,调用 SystemServer # main() 方法,即入口函数return; // 在Android 8.0之前是通过抛异常的方式来启动,这里是直接return出去,用来清空栈,提高栈帧利用率}}......// 开启 loop 循环,在后台持续监听 client socket 发来的消息,等待新的应用启动请求caller = zygoteServer.runSelectLoop(abiList);} catch (Throwable ex) {Log.e(TAG, "System zygote died with fatal exception", ex);throw ex;} finally {if (zygoteServer != null) {zygoteServer.closeServerSocket();}}// 若fork出系统进程,则加入到列表,然后继续阻塞等待;若 fork 出子进程,则退出loop循环,返回创建的应用子进程,并执行子进程的启动。if (caller != null) {caller.run();}}......
}
首先解析传入参数,新建 ZygoteServer 实例对象,然后调用 ZygoteInit # forkSystemServer() 方法来 fork 出 system_server 进程,如果返回值 Runnable r 不为空则是在子进程,即通过 fork 复制出的 system_server 进程,随后调用 Runnable # run() 方法启动 SystemServer,调用 SystemServer # main() 方法,即入口函数。之后开启 Loop 循环,在后台持续监听 client socket 发来的消息,等待新的应用启动请求,如果 fork 出系统进程,则加入到列表,然后继续阻塞等待;如果 fork 出子进程,则退出 Loop 循环,返回创建的应用子进程,并执行子进程的启动。继续跟进源码去查看一下
2、ZygoteInit # forkSystemServer()
xref: /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {......// 准备参数,然后 fork 出 system_server 进程// 返回一个 Runnable 并提供进入子进程 system_server 的入口点,如果返回空则是在父进程,即 Zygote 进程private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {......// 创建 args 数组,保存 system_server 启动的参数,uid 和 gid 都为 1000String args[] = {"--setuid=1000","--setgid=1000","--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011", // 拥有的用户组权限"--capabilities=" + capabilities + "," + capabilities,"--nice-name=system_server", // 进程名为 system_server"--runtime-args","--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,"com.android.server.SystemServer", // 启动的类名为:com.android.server.SystemServer};ZygoteArguments parsedArgs = null;int pid;try { // 按 ZygoteArguments 的格式解析封装上面保存的参数parsedArgs = new ZygoteArguments(args);Zygote.applyDebuggerSystemProperty(parsedArgs);Zygote.applyInvokeWithSystemProperty(parsedArgs);......// fork 出系统服务进程 system_serverpid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}if (pid == 0) { // 进入子进程 system_server 进程if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName); // 需等待第二个 Zygote 创建完成}zygoteServer.closeServerSocket(); // fork 时会copy socket,Zygote 原有的 socket 需要关闭return handleSystemServerProcess(parsedArgs); // system_server 进程处理自己的工作}return null;}......
}
ZygoteInit # forkSystemServer() 方法主要执行了以下几个任务:
- 创建 args 数组,保存 system_server 启动的参数,然后调用 Zygote # forkSystemServer()方法 fork 出 system_server 进程。
- 如果系统初始化了 SecondaryZygote,则需等待第二个 zygote 创建完成。
- 由于 fork 的过程会拷贝 socket,因此在 fork 出 system_server 进程后,需要关闭从 zygote 进程复制过来的 socket 连接。
- 最后调用 ZygoteInit # handleSystemServerProcess() 方法处理 system_server 进程的初始化过程。
2.1、Zygote # forkSystemServer()
xref: /frameworks/base/core/java/com/android/internal/os/Zygote.java
public class Zygote {......static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {ZygoteHooks.preFork();// 调用 native 层的方法来fork system_server 进程int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags, rlimits,permittedCapabilities, effectiveCapabilities);// 当前线程的优先级设置为新应用程序的默认值Thread.currentThread().setPriority(Thread.NORM_PRIORITY);ZygoteHooks.postForkCommon();return pid;}private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);......
}
调用 native 层方法 nativeForkSystemServer() 来 fork 出 system_server 进程,最终通过 JNI 调用到 native 层的:com_android_internal_os_Zygote_nativeForkSystemServer() 方法,该方法在 com_android_internal_os_Zygote.cpp 文件中,继续跟踪源码查看
2.1.1、Zygote # nativeForkSystemServer()
xref: /frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static const JNINativeMethod gMethods[] = { // JIN 注册的映射关系......{"nativeForkSystemServer", "(II[II[[IJJ)I", (void*)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 runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,jlong effective_capabilities) {......// 继续通过 ForkCommon 方法来进行 forkpid_t pid = zygote::ForkCommon (env, true,fds_to_close,fds_to_ignore,true);if (pid == 0) {// 进入子进程,由于 system_server 进程不需要数据隔离,所以不需要知道 pkg_data_info_list,因此传 nullptrSpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,false, nullptr, nullptr, /* is_top_app= */ false,/* pkg_data_info_list */ nullptr,/* allowlisted_data_info_list */ nullptr, false, false);} else if (pid > 0) { // 继续进入父进程,即 Zygote 进程// Zygote 进程检查子进程是否已经死亡ALOGI("System server process %d has been created", pid); // system_server 进程已创建gSystemServerPid = pid; // 将子进程 system_server 的 pid 存在 Zygote 进程的全局变量中// 有轻微的窗口提示表明系统服务进程已经挂掉,但因为还未发布该进程的 pid,因此没有注意到,所以在这里重新检查以确保其正常int status;// 函数使用详解见下面的引用介绍,通过 waitpid 函数获取状态发生变化的子进程 pid,设置 options 标志为 WNOHANG,即非阻塞// 如果 pid 指定的子进程没有结束,则立即返回 0,而非阻塞等待;如果结束了,则返回该子进程的进程号,即 pidif (waitpid(pid, & status,WNOHANG) ==pid){// 当 system_server 进程死亡后,重启 Zygote 进程ALOGE("System server process %d has died. Restarting Zygote!", pid);RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");}......}return pid;}......
方法中继续调用 Zygote :: ForkCommon() 方法来 fork 出 system_server 进程,同时根据 Zygote :: ForkCommon() 方法返回的进程 pid 进行判断,如果 pid > 0 则继续进入父进程,即 Zygote 进程;如果 pid = 0 表示 system_server 子进程创建成功,进入 system_server 进程,继续调用 SpecializeCommon() 方法。
2.1.2、Zygote # ForkCommon()
xref: /frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
pid_t zygote::ForkCommon(JNIEnv*env, bool is_system_server,const std::vector<int>&fds_to_close,const std::vector<int>&fds_to_ignore,bool is_priority_fork,bool purge) {// 注册子进程信号监听器 SigChldHandler,监听子进程的死亡,当子进程死亡后,会产生一个信号,Zygote 进程收到// 该信号后就会调用 SigChldHandler() 函数进行处理SetSignalHandlers();......// 通过 Linux 的 fork() 系统调用创建一个新的进程,即创建当前进程的一个副本,使得两个进程在执行相同的代码// 但是在不同的内存空间中运行pid_t pid = fork();if (pid == 0) { // 子进程,这里指 system_server 进程if (is_priority_fork) { // 根据条件设置进程优先级setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);} else {setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);}// 预先设置进程的一些属性,如设置 M_SET_ZYGOTE_CHILD 表示自己不是 Zygote 进程 等PreApplicationInit();// 关闭并清除文件描述符DetachDescriptors(env, fds_to_close, fail_fn);......} else {ALOGD("Forked child process %d", pid);}......return pid;}
分析代码可知,首先通过 SetSignalHandlers() 方法注册子进程信号监听器 SigChldHandler,用来监听子进程的死亡,当子进程死亡后,会产生一个信号,Zygote 进程收到该信号后就会调用 SigChldHandler() 方法进行处理。需要注意的是:Zygote 的信号监听器,关注的是 Zygote fork 出的所有的子进程,而不只是 system_server 进程(每次创建一个新的进程时,Zygote 都会注册对应的监听器)。
然后通过 Linux 的 fork() 系统调用创建一个新的进程,即创建当前进程的一个副本,使得两个进程在执行相同的代码,但是在不同的内存空间中运行。其中的拷贝复制过程,这里不再详述,感兴趣的童鞋可以去查一些 Linux 相关的资料。
2.1.3、Zygote # SpecializeCommon()
xref: /frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static void SpecializeCommon(JNIEnv*env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags,jobjectArray rlimits, jlong permitted_capabilities,jlong effective_capabilities, jint mount_external,jstring managed_se_info, jstring managed_nice_name,bool is_system_server, bool is_child_zygote,jstring managed_instruction_set, jstring managed_app_data_dir,bool is_top_app, jobjectArray pkg_data_info_list,jobjectArray allowlisted_data_info_list, bool mount_data_dirs,bool mount_storage_dirs) {const char*process_name = is_system_server ? "system_server" : "zygote"; // 进程名......if (!is_system_server && getuid() == 0) {// 对于非 system_server 子进程,则需创建进程组 groupconst int rc = createProcessGroup(uid, getpid());if (rc == -EROFS) {ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");} else if (rc != 0) {ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));}}SetGids(env, gids, is_child_zygote, fail_fn); // 设置进程 groupSetRLimits(env, rlimits, fail_fn); // 设置资源 limitif (need_pre_initialize_native_bridge) {android::PreInitializeNativeBridge (app_data_dir.has_value() ? app_data_dir.value().c_str(): nullptr,instruction_set.value().c_str());}if (is_system_server) {// 如果是 system_server 则预加载 system_server 的类加载器,并绑定 system_server selinux 域env -> CallStaticObjectMethod(gZygoteInitClass, gGetOrCreateSystemServerClassLoader);if (env -> ExceptionCheck()) {env -> ExceptionClear();}}......const char*se_info_ptr = se_info.has_value() ? se_info.value().c_str() : nullptr;const char*nice_name_ptr = nice_name.has_value() ? nice_name.value().c_str() : nullptr;// selinux 上线文环境 contextif (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,is_system_server, se_info_ptr, nice_name_ptr));}// 设置线程名为: system_server,方便调试if (nice_name.has_value()) {SetThreadName(nice_name.value());} else if (is_system_server) {SetThreadName("system_server");}......if (is_system_server) {// 调用对应 Zygote.java 的 callPostForkSystemServerHooks() 方法env -> CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks, runtime_flags);if (env -> ExceptionCheck()) {fail_fn("Error calling post fork system server hooks.");}// TODO(b/117874058): Remove hardcoded label here.static const char*kSystemServerLabel = "u:r:system_server:s0";if (selinux_android_setcon(kSystemServerLabel) != 0) {fail_fn(CREATE_ERROR("selinux_android_setcon(%s)", kSystemServerLabel));}}......env -> CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,is_system_server, is_child_zygote, managed_instruction_set);// 进程优先级设置为默认值setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_DEFAULT);......}......
对新创建的 system_server 进程进行配置,如进程名、进程 group 、资源 limit、预加载 system_server 的类加载器,并绑定 system_server selinux 域,最后设置进程优先级为默认值。
2.2、ZygoteInit # handleSystemServerProcess()
xref: /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {......private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {Os.umask(S_IRWXG | S_IRWXO); // 为用户文件创建权限掩码if (parsedArgs.mNiceName != null) {Process.setArgV0(parsedArgs.mNiceName); // 设置进程名为 system_server}// 加载指定路径下的 SystemServer 文件final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");if (systemServerClasspath != null) {// 路径不为空则加载执行 dex 优化操作,其内部工作是通过 AIDL 通信将命令参数传给 Installd 来完成的performSystemServerDexOpt(systemServerClasspath); // Capturing profiles is only supported for debug or eng builds since selinux normally prevents it.if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) {try {Log.d(TAG, "Preparing system server profile");prepareSystemServerProfile(systemServerClasspath); // 加载 SystemServer 属性配置文件} catch (Exception e) {Log.wtf(TAG, "Failed to set up system server profile", e);}}}if (parsedArgs.mInvokeWith != null) {String[] args = parsedArgs.mRemainingArgs;// 如果 SystemServer 类路径不为空,则需将其拼接到前面封装的 ZygoteArguments 的后面if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2];amendedArgs[0] = "-cp";amendedArgs[1] = systemServerClasspath;System.arraycopy(args, 0, amendedArgs, 2, args.length);args = amendedArgs;}// 调用 WrapperInit # execApplication 方法使用包装器命令启动并执行运行时应用程序进程WrapperInit.execApplication(parsedArgs.mInvokeWith,parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,VMRuntime.getCurrentInstructionSet(), null, args);throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");} else {// 构建获取 SystemServer 类加载器,并设置给当前的线程ClassLoader cl = getOrCreateSystemServerClassLoader();if (cl != null) {Thread.currentThread().setContextClassLoader(cl);}// 将剩余参数交给 ZygoteInit.zygoteInit() 方法完成 SystemServer 进程的初始化return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, cl);}}......
}
首先,为用户文件创建权限掩码,并设置进程名为:system_server。然后,加载指定路径下的 SystemServer 文件,并执行 dex 优化操作。最后构建获取 SystemServer 类加载器并设置给当前的线程,最后将剩余参数交给 ZygoteInit # zygoteInit() 方法完成 SystemServer 进程的初始化。
2.3 ZygoteInit # zygoteInit()
xref: /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {......public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {if (RuntimeInit.DEBUG) {Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");RuntimeInit.redirectLogStreams(); // 重定向 log 日志输出// 进程初始化配置,如设置异常捕获 Handler、时区、重置 LogManager 等等RuntimeInit.commonInit();// native 层初始化 -- 打开/dev/binder 驱动,映射内核的地址空间,创建 binder 线程用于 IPC 通信ZygoteInit.nativeZygoteInit();return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,classLoader);}......private static native void nativeZygoteInit();
}
方法流程如下:
- 日志流重定向,将系统输出和系统错误重定向到 Android 日志。
- 进程初始化配置,如设置异常捕获 Handler、时区、重置 LogManager 等等。
- native 层初始化,打开 /dev/binder 驱动,映射内核的地址空间,创建 binder 线程用于 IPC 通信。
- 调用 RuntimeInit # applicationInit() 方法,返回创建的 Runnable 对象。
2.3.1 ZygoteInit # nativeZygoteInit()
ZygoteInit # nativeZygoteInit() 方法,通过 JNI 调用到 native 层的:com_android_internal_os_ZygoteInit_nativeZygoteInit() 方法,该方法在 AndroidRuntime.cpp 文件中,跟踪源码查看
......static AndroidRuntime* gCurRuntime = NULL;......static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv*env, jobject clazz) {// gCurRuntime 在 AndroidRuntime.cpp 中定义并赋值的,但其实现是在其子类 AppRuntime 类中gCurRuntime -> onZygoteInit();}......int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv*env) {const JNINativeMethod methods[] = {{"nativeZygoteInit", "()V",( void*)com_android_internal_os_ZygoteInit_nativeZygoteInit },};return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",methods, NELEM(methods));}......AndroidRuntime::AndroidRuntime(char*argBlockStart, const size_t argBlockLength) :mExitWithoutCleanup(false),mArgBlockStart(argBlockStart),mArgBlockLength(argBlockLength) {init_android_graphics();// Pre-allocate enough space to hold a fair number of options.mOptions.setCapacity(20);assert (gCurRuntime == NULL); // one per processgCurRuntime = this;}......
在方法中继续调用 gCurRuntime :: onZygoteInit() 方法,可以看到 gCurRuntime 是 AndroidRuntime 类型的指针,并且在 AndroidRuntime 的构造方法中将自身 this 赋值给 gCurRuntime,即 AndroidRuntime 初始化时将 gCurRuntime 指向对象自身,那么 AndroidRuntime 是在何时初始化的呢?
2.3.2 app_main # main()
我们知道,app_main.cpp 的 main() 函数是 App 进程的主入口,启动解释的运行时,然后启动应用程序,进到源码中查看
xref: /frameworks/base/cmds/app_process/app_main.cpp
class AppRuntime : public AndroidRuntime {public:AppRuntime( char*argBlockStart, const size_t argBlockLength):AndroidRuntime(argBlockStart, argBlockLength), mClass(NULL){}......virtual void onZygoteInit (){ // 获取进程唯一实例,内部首先判断是否变量为NULL,非NULL则直接返回,反之才会调用其构造函数创建ProcessState实例// 因此同一进程有且只有一个 ProcessState 实例sp<ProcessState> proc = ProcessState::self ();ALOGV("App process: starting thread pool.\n");// 启动 Binder 线程池,方法内部继续调用 spawnPooledThread() 函数真正去启动线程池proc -> startThreadPool(); }......String8 mClassName;Vector<String8> mArgs;jclass mClass;};......int main(int argc, char*const argv[]) {......// 创建 AppRuntimeAppRuntime runtime (argv[0], computeArgBlockSize(argc, argv));......if (!niceName.isEmpty()) {runtime.setArgv0(niceName.string(), true /* setProcName */);}if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);} else {fprintf(stderr, "Error: no class name or --zygote supplied.\n");app_usage();LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");}}
在 app_main.cpp 的 main() 函数中创建了 AppRuntime,继续查看可知 AppRuntime 是 AndroidRuntime 的子类,在初始化过程中,构建 AppRuntime 的同时调用 AndroidRuntime 的构造函数来进行初始化,并将自身 this 赋值给 gCurRuntime。
因此经过分析可知,上一小节的 gCurRuntime 指向的就是 AppRuntime 对象,也即调用的是 AppRuntime # onZygoteInit() 方法,其方法内首先通过 ProcessState::self () 方法获取进程唯一实例,然后调用 ProcessState::startThreadPool() 方法启动 Binder 线程池,进而 SystemServer 进程就可以使用 Binder 与其他进程进行通信。
ProcessState: 继承自RefBase,其在同一进程内是唯一的,主要用于初始化 Binder 设备( 即打开 binder 设备文件/dev/binder节点) ,并将设备文件映射到进程的地址空间。Binder 线程池中的每一个线程都可以通过它与 Binder 驱动程序建立连接。简言之,其主要工作是调用 open() 函数打开 /dev/binder 驱动设备,再利用 mmap() 映射内核的地址空间, 将 Binder 驱动的 fd 赋值 ProcessState 对象中的变量 mDriverFD,用于交互操作。
2.3.3 RuntimeInit # applicationInit()
xref: /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {......private static final native void nativeSetExitWithoutCleanup(boolean exitWithoutCleanup);......protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {// true 代表应用程序退出时不调用 AppRuntime.onExit(),否则会在退出前调用,将导致剩余的运行线程在进程实际退出之前崩溃nativeSetExitWithoutCleanup(true);VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);// 解析参数final Arguments args = new Arguments(argv);// The end of of the RuntimeInit event (see #zygoteInit).Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// 余下的参数传给即将要启动的类的静态 main 方法return findStaticMain(args.startClass, args.startArgs, classLoader);}......
}
首先调用 native 层的 nativeSetExitWithoutCleanup() 方法,且入参为 true,true 表示应用程序退出时不调用 AppRuntime.onExit() 方法,否则将会在退出前调用,导致剩余的运行线程在进程实际退出之前崩溃。然后解析参数,并继续调用 RuntimeInit # findStaticMain() 方法,将参数传给即将要启动的类的静态 main() 方法。
2.3.4 RuntimeInit # findStaticMain()
xref: /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {......protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {Class<?> cl;try { // 通过反射机制得到 SystemServer 类cl = Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {throw new RuntimeException("Missing class when invoking static main " + className, ex);}Method m;try { // 获取 SystemServer # main() 方法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);}// 判断 main 方法是不是 public static 类型int modifiers = m.getModifiers();if (!(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {throw new RuntimeException("Main method is not public and static on " + className);}// 将获取的 Method 和参数封装成 MethodAndArgsCaller 对象返回,MethodAndArgsCaller 实现了 Runnable 接口return new MethodAndArgsCaller(m, argv);}......
}
首先,此处启动的类名为 fork 子进程时保存到 args 数组中的:com.android.server.SystemServer,并通过反射机制得到 SystemServer 类,然后通过 Class # getMethod() 方法获取 SystemServer 类的 main() 方法,再通过 Method # getModifiers() 方法获取方法的权限修饰,如果不是 public static 类型的则抛出异常,最后将获取的 Method 和参数封装成 MethodAndArgsCaller 对象返回,即返回到 1 ZygoteInit # main() 这节中 ZygoteInit # main() 方法中 forkSystemServer() 方法返回的 Runnable r,如果 r!=null 会调用这个 Runnable # run() 方法。
2.3.5 MethodAndArgsCaller # run()
xref: /frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {......static class MethodAndArgsCaller implements Runnable {// 待反射调用的方法private final Method mMethod;// 待反射调用方法的参数数组private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}public void run() {try { // 通过反射机制调用的是 SystemServer # main() 方法并传入传递过来的参数mMethod.invoke(null, new Object[]{mArgs});} 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);}}}
}
MethodAndArgsCaller # run() 方法中使用了 invoke 反射调用,通过反射机制调用的是 SystemServer # main() 方法并传入传递过来的参数,至此 SystemServer 的 main() 方法得以执行,继续查看源码
3 SystemServer # main()
xref: /frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {......// Zygote 启动 SystemServer 的主要入口public static void main(String[] args) {// 初始 SystemServer 对象,再调用其 run() 方法new SystemServer().run();}......private void run() {TimingsTraceAndSlog t = new TimingsTraceAndSlog();try {t.traceBegin("InitBeforeStartServices");// 记录进程启动的信息SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));......// 如果未设置,则将时区属性默认为GMTString timezoneProperty = SystemProperties.get("persist.sys.timezone");if (!isValidTimeZoneId(timezoneProperty)) {Slog.w(TAG, "persist.sys.timezone is not valid (" + timezoneProperty + "); setting to GMT.");SystemProperties.set("persist.sys.timezone", "GMT");}......// 设置虚拟机的库文件,在 Android6.0 上用的是 libart.soSystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());// 清除 vm 内存增长上限,由于启动过程需要较多的虚拟机内存空间VMRuntime.getRuntime().clearGrowthLimit();// 针对部分设备依赖于运行时就产生指纹信息,因此需在开机完成前定义好Build.ensureFingerprintProperty();// 在 system_server 中,访问环境路径前,需要明确地指定用户Environment.setUserRequired(true);// 在 system_server 中,需对传入的 bundle 进行解压缩,以避免抛出 BadParcelableException 异常BaseBundle.setShouldDefuse(true);// 在 system_server 中,当对异常进行打包时,应包括堆栈跟踪Parcel.setStackTraceParceling(true);// Ensure binder calls into the system always run at foreground priority.// 确保当前系统进程的 binder 调用,总是以前台优先级运行BinderInternal.disableBackgroundScheduling(true);// 在 system server 中,增加 binder 线程的数量,最大值为 31BinderInternal.setMaxThreads(sMaxBinderThreads);// 为主 Looper thread 做准备android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);android.os.Process.setCanSelfBackground(false);Looper.prepareMainLooper(); // 创建消息 LooperLooper.getMainLooper().setSlowLogThresholdMs(SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);SystemServiceRegistry.sEnableServiceNotFoundWtf = true;// 加载 android_servers.so 库,该库包含的源码在frameworks/base/services/目录下System.loadLibrary("android_servers");initZygoteChildHeapProfiling();// debug 模式下,构建并生成一个线程来监视 fd 泄漏if (Build.IS_DEBUGGABLE) {spawnFdLeakCheckThread();}// 检测上次关机过程是否失败,该方法可能不会返回performPendingShutdown();// 初始化系统上下文createSystemContext();// 调用每个进程主线模块初始化ActivityThread.initializeMainlineModules();// 设置转储服务ServiceManager.addService("system_server_dumper", mDumper);mDumper.addDumpable(this);// 创建系统服务管理 SystemServiceManager,对系统服务进行创建、启动和生命周期管理mSystemServiceManager = new SystemServiceManager(mSystemContext);mSystemServiceManager.setStartInfo(mRuntimeRestart,mRuntimeStartElapsedTime, mRuntimeStartUptime);mDumper.addDumpable(mSystemServiceManager);// 将 mSystemServiceManager 添加到本地服务的成员 sLocalServiceObjects 中// LocalServices 通过用静态 Map 变量 sLocalServiceObjects,来保存以服务类名为key,以具体服务对象为value的Map结构LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);// 为可以并行化的 init 任务准备线程池SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();mDumper.addDumpable(tp);// 为 system server 加载预安装的系统字体,以便 WMS 等服务可以开始使用Typeface。// 注意,字体不仅用于文本渲染,还用于某些文本操作(例如textutils . makesafeforpresentation())if (Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {Typeface.loadPreinstalledSystemFontMap();}// 如果这是一个可调试的构建并且设置了系统属性,则附加 JVMTI 代理if (Build.IS_DEBUGGABLE) {......}} finally {t.traceEnd(); // InitBeforeStartServices}// 设置默认的应用 WTF HandlerRuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf);try { // 启动服务t.traceBegin("StartServices");startBootstrapServices(t); // 启动引导服务startCoreServices(t); // 启动核心服务startOtherServices(t); // 启动其他服务} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;} finally {t.traceEnd(); // StartServices}StrictMode.initVmDefaults(null); // 为当前的虚拟机初始化 VmPolicy......// 省略记录和日志输出等// 开启 Looper 循环,一直循环执行Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}......
}
作为 SystemServer 的入口方法,SystemServer # main() 方法很简单,初始 SystemServer 对象并调用其 run() 方法,配置属性、启动服务等任务都在 SystemServer # run() 方法中,这个方法很长,其主要执行了以下任务:
- 记录进程启动的信息,配置各种属性信息,然后创建当前线程 Looper 对象,通过 System # loadLibrary() 方法加载静态库 android_servers.so;
- 调用 SystemServer # performPendingShutdown() 方法,检测上次关机过程是否失败;
- 调用 SystemServer # createSystemContext() 方法创建并初始化系统上下文;
- 创建 SystemServiceManager 对象,用来管理系统服务 (SystemService) 的创建、启动和其他生命周期事件的;
- 创建服务初始化线程池 SystemServerInitThreadPool,为可以并行化的 init 任务准备线程池,使得系统服务的初始化过程可并行;
- 启动引导服务、核心服务以及其他服务;
- 通过 Looper # loop() 方法开启循环,等待消息队列 MessageQueue 中的消息到来,则马上进入执行状态。
3.1 SystemServer # performPendingShutdown()
xref: /frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {......private void performPendingShutdown() {// 读取系统属性配置 ShutdownThread.SHUTDOWN_ACTION_PROPERTYfinal String shutdownAction = SystemProperties.get(ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");if (shutdownAction != null && shutdownAction.length() > 0) {boolean reboot = (shutdownAction.charAt(0) == '1');final String reason;if (shutdownAction.length() > 1) {reason = shutdownAction.substring(1, shutdownAction.length());} else {reason = null;}// 重启保护,如果需重启恢复以更新应用,应确保在需要时正确执行uncrypt,且如果'/cache/recovery/block.map'没被创建则停止重启if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {File packageFile = new File(UNCRYPT_PACKAGE_FILE);if (packageFile.exists()) {String filename = null;try {filename = FileUtils.readTextFile(packageFile, 0, null);} catch (IOException e) {Slog.e(TAG, "Error reading uncrypt package file", e);}if (filename != null && filename.startsWith("/data")) {if (!new File(BLOCK_MAP_FILE).exists()) {Slog.e(TAG, "Can't find block map file, uncrypt failed or " +"unexpected runtime restart?");return;}}}}Runnable runnable = new Runnable() {@Overridepublic void run() {synchronized (this) { // 当"sys.shutdown.requested"值为 1 时,则会重启,值不为空时,且不为 1 时,则会关机ShutdownThread.rebootOrShutdown(null, reboot, reason);}}};// ShutdownThread 必须运行在一个能够显示 UI 的 Looper 上,即 UI 主线程上启动 ShutdownThread 的rebootOrShutdownMessage msg = Message.obtain(UiThread.getHandler(), runnable);msg.setAsynchronous(true);UiThread.getHandler().sendMessage(msg);}}......
}
读取系统属性配置 ShutdownThread.SHUTDOWN_ACTION_PROPERTY,如果获取到的值为 1 时,则会重启;值不为空且不为 1 时,则会关机。
注意:ShutdownThread 必须运行在一个能够显示 UI 的 Looper 上,即 UI 主线程上。
3.2 SystemServer # createSystemContext()
xref: /frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {......private void createSystemContext() {// 创建获取 system_server 进程的上下文信息,并设置默认主题ActivityThread activityThread = ActivityThread.systemMain();mSystemContext = activityThread.getSystemContext();mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);// 创建获取 SystemUi 的上下文信息并设置默认主题final Context systemUiContext = activityThread.getSystemUiContext();systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);}......
}
首先在 ActivityThread # systemMain() 方法中创建获取 ActivityThread 实例对象,然后调用 ActivityThread # attach() 方法,过程中会创建 Instrumentation,ContextImpl,Application 等实例对象。ActivityThread # getSystemContext() 方法中通过 ContextImpl # createSystemContext() 方法创建 system_server 进程的上下文信息等,然后再给上下文设置默认主题信息,具体代码比较易懂,感兴趣的同学自行跟踪查看代码。
3.3 SystemServiceManager
xref: /frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public final class SystemServiceManager implements Dumpable {......private final Context mContext;// Services that should receive lifecycle events.private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();......SystemServiceManager(Context context) {mContext = context;}// 启动 Service,入参为待启动的服务类名,返回服务的实例public SystemService startService(String className) {// 内部通过反射调用获取到待启动服务的类final Class<SystemService> serviceClass = loadClassFromLoader(className,this.getClass().getClassLoader());return startService(serviceClass); // 启动获取到的待启动服务类}......public <T extends SystemService> T startService(Class<T> serviceClass) {try {......// 创建待启动服务类的实例对象final T service;try {Constructor<T> constructor = serviceClass.getConstructor(Context.class);service = constructor.newInstance(mContext);} catch (InstantiationException ex) {...... // 异常捕获并抛出}startService(service); // 启动服务类return service;} finally {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}}public void startService(@NonNull final SystemService service) {mServices.add(service); // 将启动的服务注册到已启动的服务列表中long time = SystemClock.elapsedRealtime();try {service.onStart(); // 服务启动后,回调其 Service # onStart() 方法} catch (RuntimeException ex) {throw new RuntimeException("Failed to start service " + service.getClass().getName()+ ": onStart threw an exception", ex);}warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");}......
}
SystemServiceManager 是用来管理系统服务 (SystemService) 的创建、启动和其他生命周期事件的。其内部的 mServices 用来存储启动的 Service 的列表,回调 services 的 onStart() 和 onBootPhase() 生命周期时都需要遍历该 List。
3.4 SystemServer # startBootstrapServices()
xref: /frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {......private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {t.traceBegin("startBootstrapServices");// 启动 Watchdog 监控启动引导服务时是否会死锁t.traceBegin("StartWatchdog");final Watchdog watchdog = Watchdog.getInstance();watchdog.start();t.traceEnd();...... // 平台配套服务由 AMS、PMS 以及将来可能的其他服务使用t.traceBegin("PlatformCompat");PlatformCompat platformCompat = new PlatformCompat(mSystemContext);ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,new PlatformCompatNative(platformCompat));AppCompatCallbacks.install(new long[0]);t.traceEnd();// FileIntegrityService 响应来自应用程序和系统的请求。需在资源准备好之后,在应用程序(或系统中的第一个客户)运行之前运行t.traceBegin("StartFileIntegrityService");mSystemServiceManager.startService(FileIntegrityService.class);t.traceEnd();t.traceBegin("StartInstaller"); // 阻塞等待 Installd 服务启动完成且与其建立 socket 通道Installer installer = mSystemServiceManager.startService(Installer.class);t.traceEnd();// 在某些情况下,在启动应用程序后,需要访问设备标识符,因此要在 activity manager 之前注册t.traceBegin("DeviceIdentifiersPolicyService");mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);t.traceEnd();t.traceBegin("UriGrantsManagerService"); // 启动 Uri 授权管理服务mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);t.traceEnd();t.traceBegin("StartPowerStatsService"); // 启动 PowerStatsService 服务,用于功率统计mSystemServiceManager.startService(PowerStatsService.class);t.traceEnd();t.traceBegin("StartIStatsService");startIStatsService(); // 阻塞调用,启动 IStats 服务t.traceEnd();// 在 ActivityManager 之前启动 MemtrackProxyService 服务,以免调用 Memtrack::getMemory() 方法失败t.traceBegin("MemtrackProxyService");startMemtrackProxyService();t.traceEnd();// Activity manager 负责显示t.traceBegin("StartActivityManager"); // 启动 ActivityTaskManagerService 服务// ATMS 是 Android 10 中新增的,本来都是 ActivityManagerService 来管理// Google考虑到AMS职责太多、代码太庞大,所以单独拆出来ATMS用于管理Activity及其容器类如Task、Stack、Display等,分担部分职责ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm); // 启动 ActivityManagerService 服务mActivityManagerService.setSystemServiceManager(mSystemServiceManager); // AMS 设置 SystemServiceManagermActivityManagerService.setInstaller(installer); // AMS 设置 InstallermWindowManagerGlobalLock = atm.getGlobalLock(); // 获取 ATMS 的成员 mGlobalLock 赋值给 mWindowManagerGlobalLockt.traceEnd();// DataLoaderManagerService 数据加载器管理服务需要在包管理服务之前启动t.traceBegin("StartDataLoaderManagerService");mDataLoaderManagerService = mSystemServiceManager.startService(DataLoaderManagerService.class);t.traceEnd();// IncrementalService 服务需要在包管理服务之前启动t.traceBegin("StartIncrementalService");mIncrementalServiceHandle = startIncrementalService();t.traceEnd();// 因有其他业务需要用到,因此 PowerManagerService 电源管理服务要尽早启动t.traceBegin("StartPowerManager");mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);t.traceEnd();t.traceBegin("StartThermalManager");mSystemServiceManager.startService(ThermalManagerService.class);t.traceEnd();t.traceBegin("StartHintManager");mSystemServiceManager.startService(HintManagerService.class);t.traceEnd();// 电源管理服务已经启动,Activity Manager 初始化电源管理特性t.traceBegin("InitPowerManagement");mActivityManagerService.initPowerManagement();t.traceEnd();// 启动恢复系统,以防需要重启t.traceBegin("StartRecoverySystemService");mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class);t.traceEnd();// 已经启动并运行了操作系统的基本要素,但须注意,有可能会陷入运行时重启循环RescueParty.registerHealthObserver(mSystemContext);PackageWatchdog.getInstance(mSystemContext).noteBoot();t.traceBegin("StartLightsService"); // 启动 LightsService 服务,管理 LED 和显示mSystemServiceManager.startService(LightsService.class);t.traceEnd();t.traceBegin("StartSidekickService");if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);}t.traceEnd();// 启动 DisplayManagerService 服务,需在包管理服务之前启动,用于提供显示t.traceBegin("StartDisplayManager");mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);t.traceEnd();// 在初始化包管理服务之前,我们需要默认的显示t.traceBegin("WaitForDisplay");mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);t.traceEnd();......t.traceBegin("StartDomainVerificationService");DomainVerificationService domainVerificationService = new DomainVerificationService(mSystemContext, SystemConfig.getInstance(), platformCompat);mSystemServiceManager.startService(domainVerificationService);t.traceEnd();t.traceBegin("StartPackageManagerService");try { // 启动包管理服务 PackageManagerServiceWatchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");mPackageManagerService = PackageManagerService.main(mSystemContext, installer,domainVerificationService, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,mOnlyCore);} finally {Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");}// 包管理服务已经启动,注册 dex load reporter 捕获系统服务加载的任何 dex 文件,这些 dex 文件将被后台dexoptservice优化SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);mFirstBoot = mPackageManagerService.isFirstBoot(); // 是否第一次启动mPackageManager = mSystemContext.getPackageManager();t.traceEnd();if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__PACKAGE_MANAGER_INIT_READY,SystemClock.elapsedRealtime());}......t.traceBegin("StartUserManagerService"); // 启动 UserManagerService 服务mSystemServiceManager.startService(UserManagerService.LifeCycle.class);t.traceEnd();t.traceBegin("InitAttributerCache");AttributeCache.init(mSystemContext); // 初始化用于缓存从包中获取的属性缓存t.traceEnd();// 为系统进程设置 Application 实例并开始t.traceBegin("SetSystemProcess");mActivityManagerService.setSystemProcess();t.traceEnd();// PackageReceiver 依赖于 Activity Service 服务来注册platformCompat.registerPackageReceiver(mSystemContext);// 使用 ActivityManager 实例完成 Watchdog 设置,并侦听重新启动// 只有在 ActivityManagerService 作为系统进程且正确启动后才能执行此操作t.traceBegin("InitWatchdog");watchdog.init(mSystemContext, mActivityManagerService);t.traceEnd();// DisplayManagerService 需要设置与显示调度相关的策略,因为setSystemProcess()会因为setProcessGroup而覆盖策略mDisplayManagerService.setupSchedulerPolicies();// 启动 OverlayManagerService 服务,用于管理叠加包t.traceBegin("StartOverlayManagerService");mSystemServiceManager.startService(new OverlayManagerService(mSystemContext));t.traceEnd();// 启动 SensorPrivacyService 服务,传感器有关如重力加速、光线等t.traceBegin("StartSensorPrivacyService");mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));t.traceEnd();if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {// 更新 DisplayManagerService 服务mActivityManagerService.updateSystemUiContext();LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();}// 启动 SensorService 传感器服务,其需要访问包管理服务、应用ops服务和权限服务,因此我们在它们之后启动它t.traceBegin("StartSensorService"); mSystemServiceManager.startService(SensorService.class);t.traceEnd();t.traceEnd(); // startBootstrapServices}......
}
代码比较长,方法中按序启动了很多的引导服务,有:Installer、ActivityTaskManagerService、ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService、OverlayManagerService 和 SensorService 等服务,具体可查看代码注释。
3.5 SystemServer # startCoreServices()
xref: /frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {......private void startCoreServices(@NonNull TimingsTraceAndSlog t) {t.traceBegin("startCoreServices");// 启动 SystemConfigService 系统配置服务t.traceBegin("StartSystemConfigService");mSystemServiceManager.startService(SystemConfigService.class);t.traceEnd();t.traceBegin("StartBatteryService");// 启动 BatteryService 电池服务,用于统计电池电量,需结合 LightServicemSystemServiceManager.startService(BatteryService.class);t.traceEnd();// 启动 UsageStatsService 服务,用于统计应用使用情况t.traceBegin("StartUsageService");mSystemServiceManager.startService(UsageStatsService.class);mActivityManagerService.setUsageStatsManager(LocalServices.getService(UsageStatsManagerInternal.class));t.traceEnd();// 启动 WebViewUpdateService 服务,用于观察可更新的 WebView 是否处于就绪状态,并监视更新安装if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {t.traceBegin("StartWebViewUpdateService");mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);t.traceEnd();}// 启动 CachedDeviceStateService 服务,用于追踪和缓存设备状态t.traceBegin("StartCachedDeviceStateService");mSystemServiceManager.startService(CachedDeviceStateService.class);t.traceEnd();// 启动 BinderCallsStatsService 服务,用于追踪在 binder 调用中花费的 cpu 时间t.traceBegin("StartBinderCallsStatsService");mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);t.traceEnd();// 启动 LooperStatsService 服务,用于追踪在处理程序中处理消息所花费的时间t.traceBegin("StartLooperStatsService");mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);t.traceEnd();// 启动 RollbackManagerService 服务,用于管理 apk 安装包的回滚t.traceBegin("StartRollbackManagerService");mSystemServiceManager.startService(ROLLBACK_MANAGER_SERVICE_CLASS);t.traceEnd();// 启动 NativeTombstoneManagerService 服务,用于追踪 native tombstonest.traceBegin("StartNativeTombstoneManagerService");mSystemServiceManager.startService(NativeTombstoneManagerService.class);t.traceEnd();// 启动 BugreportManagerService 服务,用于捕获并报告 bugt.traceBegin("StartBugreportManagerService");mSystemServiceManager.startService(BugreportManagerService.class);t.traceEnd();// 启动 GPU 和 GPU 驱动服务,用于为 GPU 和 GPU 驱动程序提供服务t.traceBegin("GpuService");mSystemServiceManager.startService(GpuService.class);t.traceEnd();t.traceEnd(); // startCoreServices}......
}
该方法用于启动一些在启动引导服务过程中没有相互依赖的基本服务,如:SystemConfigService、BatteryService、BinderCallsStatsService、BugreportManagerService 等服务,这些服务很少或基本不依赖于别的服务。
3.5 SystemServer # startOtherServices()
xref: /frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {......private ContentResolver mContentResolver;......private void startOtherServices(@NonNull TimingsTraceAndSlog t) {t.traceBegin("startOtherServices");final Context context = mSystemContext;WindowManagerService wm = null;......InputManagerService inputManager = null;......try {......t.traceBegin("StartKeyAttestationApplicationIdProviderService");ServiceManager.addService("sec_key_att_app_id_provider",new KeyAttestationApplicationIdProviderService(context));......mContentResolver = context.getContentResolver(); // 获取 ContentResolver 实例对象...... // 安装 ContentProvidermActivityManagerService.getContentProviderHelper().installSystemProviders();......t.traceBegin("StartInputManagerService"); // 启动 InputManagerService 服务inputManager = new InputManagerService(context);......t.traceBegin("StartWindowManagerService"); // 启动 WindowManagerService 服务mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);ServiceManager.addService(Context.INPUT_SERVICE, inputManager,/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);t.traceBegin("SetWindowManagerService"); // ActivityManagerService 设置 WindowManagerServicemActivityManagerService.setWindowManager(wm);......} catch (Throwable e) {......// 日志输出并抛出异常}......t.traceBegin("MakeDisplayReady");try {wm.displayReady();} catch (Throwable e) {reportWtf("making display ready", e);}t.traceEnd();......t.traceBegin("MakeInputManagerServiceReady");try {if (inputManagerF != null) {inputManagerF.systemRunning();}} catch (Throwable e) {reportWtf("Notifying InputManagerService running", e);}......// 准备好上面启动过的服务,如 WMS、PMS、DMS等t.traceBegin("MakeWindowManagerServiceReady");try {wm.systemReady();} catch (Throwable e) {reportWtf("making Window Manager Service ready", e);}mActivityManagerService.systemReady(() -> {Slog.i(TAG, "Making services ready");}, t);......t.traceEnd(); // startOtherServices}......
}
该方法代码太多,主要是启动一些非紧要和不需要立即启动的服务,如:CameraService、AlarmManagerService、InputManagerService、WindowManagerService、…、AndioServcie 等,然后准备好这些启动过的服务,等待后续客户端的调用。
三、SystemServer 启动的服务及其作用
在 system_server 进程启动中,将系统服务分为三大类:引导服务、核心服务及其他服务。下面简单的罗列下这些在 Android 系统中常见的服务及其作用。
1、引导服务
Installer :系统安装 APK 时的一个服务类,启动完成 Installer 服务之后才能启动其他的系统服务
ActivityManagerService :负责四大组件的启动、切换、调度
PowerManagerService :计算系统中与 Power 相关的计算,然后决策系统应该如何反应
LightsService :管理和显示背光 LED
DisplayManagerService :用来管理所有显示设备
UserManagerService :多用户模式管理
SensorService :为系统提供各种感应器服务
PackageManagerService :对 APK 进行安装、解析、删除、卸载等操作
…等等…
2、核心服务
DropBoxManagerService:用于生成和管理系统运行时的一些日志文件
BatteryService:管理电池相关的服务
UsageStatsService:收集用户使用每一个 App 的频率、使用时长
WebViewUpdateService:WebView 更新服务
…等等…
3、其他服务
CameraService:摄像头相关服务
AlarmManagerService:全局定时器管理服务
InputManagerService:管理输入事件
WindowManagerService:窗口管理服务
VrManagerService:VR模式管理服务
BluetoothService:蓝牙管理服务
LocationManagerService:定位管理服务,GPS、定位等
AndioServcie:音频相关管理服务
LockSettingsService:屏幕锁定服务,管理每个用户的相关锁屏信息
DeviceIdleController:Doze模式的主要驱动
DevicePolicyManagerService:提供一些系统级别的设置及属性
StatusBarManagerService:状态栏管理服务
ClipboardService:系统剪切板服务
NetworkManagementService:网络管理服务
TextServicesManagerService:文本服务,例如文本检查等
NetworkScoreService:网络评分服务
NetworkStatsService:网络状态服务
NetworkPolicyManagerService:网络策略服务
WifiP2pService:Wifi Direct服务
WifiService:Wifi服务
WifiScanningService:Wifi扫描服务
RttService:Wifi相关
EthernetService:以太网服务
ConnectivityService:网络连接管理服务
NsdService:网络发现服务
NotificationManagerService:通知栏管理服务
DeviceStorageMonitorService:磁盘空间状态检测服务
CountryDetectorService:检测用户国家
SearchManagerService:搜索管理服务
DropBoxManagerService:用于系统运行时日志的存储于管理
WallpaperManagerService:壁纸管理服务
AudioService:AudioFlinger的上层管理封装,主要是音量、音效、声道及铃声等的管理
DockObserver:如果系统有个座子,当手机装上或拔出这个座子的话,就得靠他来管理了
WiredAccessoryManager:监视手机和底座上的耳机
UsbService:USB服务
SerialService:串口服务
TwilightService:指出用户当前所在位置是否为晚上,被 UiModeManager 等用来调整夜间模式
BackupManagerService:备份服务
AppWidgetService:提供Widget的管理和相关服务
VoiceInteractionManagerService:语音交互管理服务
DiskStatsService:磁盘统计服务,供dumpsys使用
SamplingProfilerService:用于耗时统计等
NetworkTimeUpdateService:监视网络时间,当网络时间变化时更新本地时间。
CertBlacklister:提供一种机制更新SSL certificate blacklist
DreamManagerService:屏幕保护
PrintManagerService:打印服务
HdmiControlService:HDMI控制服务
FingerprintService:指纹服务
…等等…
总结
SystemServer 进程是 Zygote 启动后 fork 出的第一个进程,其本质是通过 Linux 的 fork() 系统调用来创建的。SystemServer 进程在启动过程中,先初始化系统变量、加载系统类库、创建 Context 上线文对象等。然后创建 SystemServiceManager 对象用于对系统的服务进程创建、启动和生命周期管理。之后通过 SystemServiceManager 启动系统中的引导服务、核心服务和其它服务。
注意:SystemServer 在启动服务前,会尝试与 Zygote 建立 Socket 通信,通信成功后才去启动服务,且启动的服务都单独运行在SystemServer 的各自线程中,同属于 SystemServer 进程。
相关文章:
深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解
深入学习 Android Framework 第三:深入Android S(12.0) 探索 Android Framework 之 SystemServer 进程启动详解 文章目录 深入学习 Android Framework前言一、Android 系统的启动流程1. 流程图2. 启动流程概述 二、源码详解1. 时序图2. 源代码1、ZygoteInit # main…...
搜维尔科技:【软件篇】TechViz是一款专为工程设计的专业级3D可视化软件
在沉浸式房间内深入研究您自己的 3D 数据 沉浸式房间是一个交互式虚拟现实空间,其中每个表面(墙壁、地板和天花板)都充当投影屏幕,创造高度沉浸式的体验。这就像您的 3D 模型有一个窗口,您可以在其中从不同角度走动、…...
android Handler
一、Handler的作用 1、Handler的作用是在andorid中实现线程间的通信。我们常说的说的,子线程处理逻辑,主线程更新UI是上述情况的一个子集。 二、源码分析 1、Handler源码 源码地址:http://androidxref.com/7.1.1_r6/xref/frameworks/base/co…...
【Ubuntu·系统·的Linux环境变量配置方法最全】
文章目录 概要读取环境变量的方法小技巧 概要 在Linux环境中,配置环境变量是一种常见的操作,用于指定系统或用户环境中可执行程序的搜索路径。 读取环境变量的方法 在Linux中,可以使用以下两个命令来读取环境变量: export 命令…...
Django之模板层
【1】模板之变量 在Django模板中要想使用变量关键是使用点语法。 获取值的语法是:{{ 变量名 }} Python中所有的数据类型包括函数,类等都可以调用 【2】模板之过滤器 过滤器语法 {{ obj | filter_name:param }} obj:变量名字&…...
社区论坛小程序系统源码+自定义设置+活动奖励 自带流量主 带完整的搭建教程
大家好啊,又到了罗峰来给大家分享好用的源码的时间了。今天罗峰要给大家分享的是一款社区论坛小程序系统。社区论坛已经成为人们交流、学习、分享的重要平台。然而,传统的社区论坛往往功能单一、缺乏个性化设置,无法满足用户多样化的需求。而…...
2023亚太杯数学建模C题思路解析
文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料5 最后 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 2023年第十三…...
acme在同一台服务器上设置多个Ali_key实现自动ssl申请和续期
在同一台服务器上设置多个Ali_key,您可以按照以下步骤进行操作: 首先,确保您已经安装了acme.sh工具。如果没有安装,请先安装acme.sh,您可以使用以下命令安装acme.sh: curl https://get.acme.sh | sh安装完…...
乐观锁与悲观锁
乐观锁 乐观锁是一种并发控制的机制,其核心思想是假设多个事务之间的冲突是不太可能发生的,因此在事务处理之前不会加锁,而是在事务提交的时候再检查是否有冲突。如果发现冲突,就会回滚事务,重新尝试。 实现乐观锁的方…...
【算法】堆排序
算法-堆排序 前置知识 堆(即将更新) 思路 我们现在有一个序列,怎么对它排序? 这是一个非常经典的问题,这里我们使用一个借助数据结构的算法——堆排序解决。 这里有一个序列,要对它升序排序 4 7 3 6 5 …...
51单片机应用从零开始(三)
51单片机应用从零开始(一)-CSDN博客 51单片机应用从零开始(二)-CSDN博客 详解 KEIL C51 软件的使用建立工程-CSDN博客 详解 KEIL C51 软件的使用设置工程编绎与连接程序-CSDN博客 目录 1. 用单片机控制第一个灯亮 2. 认识单片…...
如何在 Nginx Proxy Manager(NPM)上部署静态网站
前言 众所周知,我们在之前介绍过 Nginx Proxy Manager(以下简称 NPM) 这个反向代理的神器,对于一些 Docker 搭建的 Web 项目,NPM 能够很轻松地给他们做反向代理。 然而对于一些静态网站,小伙伴们可能不知道怎么用 NP…...
http的几种方法
http的几种方法在 rfc2616 中进行了定义: https://www.rfc-editor.org/rfc/rfc2616.html#page-51 HEAD方法:HEAD方法和GET方法相同,只不过服务端只返回头,不返回消息体。GET方法:用于获取资源POST方法:用于…...
var、let、const关键字的特性,以及let、const暂时性死区的作用
var、let和const都是JavaScript中的关键字,用于声明变量。 var关键字声明的变量是函数作用域或全局作用域的,它在整个函数或全局范围内都是可用的。var没有块级作用域。 let关键字声明的变量是块级作用域的,它只在包含它的代码块中可用。le…...
IDEA 高分辨率卡顿优化
VM设置优化 -Dsun.java2d.uiScale.enabledfalse 增加该条设置,关闭高分切换 https://intellij-support.jetbrains.com/hc/en-us/articles/115001260010-Troubleshooting-IDE-scaling-DPI-issues-on-Windowsintellij-support.jetbrains.com/hc/en-us/articles/1…...
【AIGC】一起学习prompt提示词(4/4)【经典】【15种提示词技巧】
写的时候并没有设计好,要做多少期,还是有始有终的比较好,为了方便阅读,我把之前的3期,改下名字,放到这里。 【AIGC】一起学习prompt提示词(1/4) 内容摘要:提示词是什么…...
Linux实战一天一个小指令--《文件管理/文件查找》
阿丹: 作为一个java程序员进行实战开发不接触linux操作系统基本上是不可能的,所以这个专题就出现了,本文章重点解决大家关于文件管理以及文件查找查看的疑惑。我将采用语法基础用法并在下面进行高级语法的总结使用,方便大家学习和…...
CocosCreator3.8神秘面纱 CocosCreator 项目结构说明及编辑器的简单使用
我们通过Dashboard 创建一个2d项目,来演示CocosCreator 的项目结构。 等待创建完成后,会得到以下项目工程: 一、assets文件夹 assets文件夹:为资源目录,用来存储所有的本地资源,如各种图片,脚本…...
JJJ:python学习笔记
p4 没有编译的过程 源码和输入得到输出 静态语言:编译型 脚本语言:解释型 p5 又叫做胶水语言 p7 p8 p10...
SpringSecurity6从入门到上天系列第七篇:讲明白SpringBoot的自动装配完善上篇文章中的结论
文章目录 一:SpringBoot的自动装配 1:从run方法到入口类内容被注册到注解解读器中。 2:解析入口类注解到加载Bean实例 大神链接:作者有幸结识技术大神孙哥为好友,获益匪浅。现在把孙哥视频分享给大家。 孙哥链接&am…...
python建筑工程项目管理系统设计与实现
目录同行可拿货,招校园代理 ,本人源头供货商功能模块分析资源与成本管理进度与质量管理技术实现要点扩展功能建议项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 功能模块分析 项目管理…...
手把手教你用STM32F103C8T6+DHT11做个智能加湿器(附完整代码和PCB文件)
从零打造智能加湿器:STM32F103C8T6与DHT11的完美组合 在干燥的秋冬季节,一台能够自动调节湿度的智能加湿器不仅能提升生活舒适度,更是电子爱好者展示技能的绝佳项目。本文将带你从元器件选型开始,逐步完成一个基于STM32F103C8T6单…...
JeecgBoot启动配置
一、引入maven指定自己的maven仓库 二、指定JDK 记得apply!!!!然后OK 三、配置MySQL数据库(尽量≥5.7版本) 四、运行db文件夹下的SQL文件 五、后端本地环境(application-dev.yml)指定好数据源 1、M…...
基于vue的非遗文化传承平台[vue]-计算机毕业设计源码+LW文档
摘要:非物质文化遗产(非遗)作为民族文化的重要组成部分,承载着人类社会的文明和历史记忆。随着现代社会的快速发展,非遗文化的传承面临着诸多挑战。为了更好地保护和传承非遗文化,本文设计并实现了一个基于…...
DS1881对数型数字电位器I²C驱动详解
1. DS1881 数字电位器驱动深度解析:面向嵌入式系统的IC对数型精密控制方案1.1 器件本质与工程定位DS1881 是 Dallas Semiconductor(后被 Maxim Integrated 收购)推出的单通道 IC 接口对数型数字电位器,其核心价值不在于“可编程电…...
抖音批量下载终极指南:免费无水印,一键搞定视频、音乐、合集
抖音批量下载终极指南:免费无水印,一键搞定视频、音乐、合集 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and brows…...
2025最权威的降AI率网站实际效果
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 有的技术方案,其旨在减低文本人工智能生成特征,这就是降AIGC工具。它…...
导入MotorCAD API(需先安装MotorCAD的Python接口)
基于Motorcad的4极6槽 内转子采用内插式磁钢 3000rpm 输出转矩 2.6Nm 效率93%外径 94mm 轴向长度70mm 功率800w 直流母线380V 永磁同步电机(永磁直流无刷)模型(PMSM或者是BLDC) 最近捣鼓了个小功率PMSM模型,用MotorCAD搭了个4极6槽内插式的&a…...
Infinity Pro书签迁移终极指南:从JSON文件到本地缓存的完整操作流程
Infinity Pro书签迁移终极指南:从JSON文件到本地缓存的完整操作流程 作为一名长期使用Infinity Pro的开发者,我深知书签迁移的痛点。每次换设备或重装系统,那些精心整理的技术资源库都要重新配置。本文将分享一套经过实战验证的迁移方案&…...
Phi-3-mini-4k-instruct新手入门:Ollama部署详解,从安装到第一个对话
Phi-3-mini-4k-instruct新手入门:Ollama部署详解,从安装到第一个对话 1. 认识Phi-3-mini-4k-instruct:轻量级AI助手 Phi-3-mini-4k-instruct是一个仅有38亿参数的轻量级语言模型,由微软团队开发。虽然体积小巧,但它在…...
