Android Framework 源码阅读系列篇章有:
- 系统启动流程一之init进程和zygote进程启动分析
- 系统启动流程二之SystemServer进程启动分析
1. SystemServer 进程启动分析
在 系统启动流程一之init进程和zygote进程启动分析 中分析 zygote 进程时,我们知道了 zygote 调用 forkSystemServer() 方法 fork 了 SystemServer 进程。
看一下 forkSystemServer() 方法:
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer) {... // 请求 fork SystemServer 进程pid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}/* For child process */// pid 为0,表示子线程,即 SystemServer 进程创建成功。if (pid == 0) { if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}zygoteServer.closeServerSocket();return handleSystemServerProcess(parsedArgs);}return null;}
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {// set umask to 0077 so new files and directories will default to owner-only permissions.Os.umask(S_IRWXG | S_IRWXO);if (parsedArgs.mNiceName != null) {Process.setArgV0(parsedArgs.mNiceName);}final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");if (systemServerClasspath != null) {// 对 SystemServer 的类路径进行 dex 优化,提升性能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);} catch (Exception e) {Log.wtf(TAG, "Failed to set up system server profile", e);}}}if (parsedArgs.mInvokeWith != null) {String[] args = parsedArgs.mRemainingArgs;// 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(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 {ClassLoader cl = null;if (systemServerClasspath != null) {// 创建类加载器,加载 SystemServer 的类路径cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);// 设置当前线程的上下文类加载器Thread.currentThread().setContextClassLoader(cl);}//将剩余的参数传递给 SystemServer,并调用 ZygoteInit.zygoteInit 初始化 SystemServerreturn ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, cl);}/* should never reach here */}
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.javapublic static final 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();// 初始化运行环境,包括设置默认的未捕获异常处理器、时区等RuntimeInit.commonInit(); // 调用 native 方法,启动 Binder 线程池,使进程能够支持 Binder 通信// 该方法在 AndroidRuntime.cpp 中实现ZygoteInit.nativeZygoteInit();// 通过反射创建应用程序的入口方法(main 方法)的 Method 对象,// 并返回一个 Runnable 对象,用于启动应用程序return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,classLoader);}
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {nativeSetExitWithoutCleanup(true);VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);// 解析传入的参数,封装到 Arguments 对象中final Arguments args = new Arguments(argv);// The end of of the RuntimeInit event (see #zygoteInit).Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// 将剩余的参数传递给启动类的静态 main 方法// args.startClass: 如果 AMS 通过 socket 传递过来的是 ActivityThreadreturn findStaticMain(args.startClass, args.startArgs, classLoader);}protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {Class<?> cl;try {// 通过类加载器加载指定的类cl = Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {throw new RuntimeException("Missing class when invoking static main " + className,ex);}Method m;try {// 通过反射获取类的 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);}int modifiers = m.getModifiers();if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {throw new RuntimeException("Main method is not public and static on " + className);}/** 返回一个 MethodAndArgsCaller 对象,该对象封装了 main 方法和参数* 这个 throw 会被 ZygoteInit.main() 捕获,并调用其 run() 方法* 这种设计可以清除所有在设置进程时所需的堆栈帧*/return new MethodAndArgsCaller(m, argv);}
// 实现 Runnable 接口的 run 方法,执行对应类的 main 方法(例如 SystemServer 或 ActivityThread)
static class MethodAndArgsCaller implements Runnable {/** method to call */private final Method mMethod;/** argument array */private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod = method;mArgs = args;}// 通过反射调用静态的 main 方法public void run() {try {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);}}}
forkSystemServer() -> handleSystemServerProcess -> ZygoteInit.zygoteInit -> RuntimeInit.applicationInit -> findStaticMain
这个链路方法调用所做的事情是:
- SystemServer 进程创建:在 forkSystemServer() 方法中fork 了 SystemServer 进程;
- SystemServer 进程初始化:在 forkSystemServer() 中执行 handleSystemServerProcess(),然后又调用 ZygoteInit.zygoteInit() 函数:
(1)初始化运行环境,像日志、网络等;
(2)nativeZygoteInit() 方法启动 binder 线程池;
(3)反射拿到 SystemServer 的 main() 函数; - SystemServer 进程运行:执行 runnable() 从而执行 SystemServer 的 main 函数;
2. SystemServer 进程运行基本流程分析
接下来看 SystemServer 的 main 函数:
// frameworks/base/services/java/com/android/server/SystemServer.javapublic static void main(String[] args) {new SystemServer().run();}
很简单,就执行了 run() 函数。
private void run() {// 创建一个计时和日志跟踪对象,用于记录系统启动的性能数据TimingsTraceAndSlog t = new TimingsTraceAndSlog();try {// 开始跟踪 "InitBeforeStartServices" 阶段t.traceBegin("InitBeforeStartServices");// 记录系统启动的进程信息到系统属性中SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));// 记录系统启动事件到 EventLog 中EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);// 如果时区未设置,默认设置为 GMTString timezoneProperty = SystemProperties.get("persist.sys.timezone");if (timezoneProperty == null || timezoneProperty.isEmpty()) {Slog.w(TAG, "Timezone not set; setting to GMT.");SystemProperties.set("persist.sys.timezone", "GMT");}// 如果系统设置了 "persist.sys.language" 等属性,将其替换为 "persist.sys.locale"if (!SystemProperties.get("persist.sys.language").isEmpty()) {final String languageTag = Locale.getDefault().toLanguageTag();SystemProperties.set("persist.sys.locale", languageTag);SystemProperties.set("persist.sys.language", "");SystemProperties.set("persist.sys.country", "");SystemProperties.set("persist.sys.localevar", "");}// 设置 Binder 调用在阻塞时发出警告Binder.setWarnOnBlocking(true);// 强制系统服务器加载安全的标签PackageItemInfo.forceSafeLabels();// 设置 SQLite 的默认同步模式为 FULLSQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;// 在设置提供程序初始化之前,停用 SQLiteCompatibilityWalFlagsSQLiteCompatibilityWalFlags.init(null);// 记录系统服务器启动日志Slog.i(TAG, "Entered the Android system server!");final long uptimeMillis = SystemClock.elapsedRealtime();EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);if (!mRuntimeRestart) {FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SYSTEM_SERVER_INIT_START,uptimeMillis);}// 设置系统属性以同步当前运行时SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());// 清除虚拟机的内存增长限制VMRuntime.getRuntime().clearGrowthLimit();// 确保设备指纹属性已定义Build.ensureFingerprintProperty();// 在系统服务器中,访问环境路径时必须显式指定用户Environment.setUserRequired(true);// 在系统服务器中,任何传入的 Bundle 都应被拆解以避免抛出 BadParcelableExceptionBaseBundle.setShouldDefuse(true);// 在系统服务器中,序列化异常时包含堆栈跟踪Parcel.setStackTraceParceling(true);// 确保系统服务器中的 Binder 调用始终以前台优先级运行BinderInternal.disableBackgroundScheduling(true);// 增加系统服务器中的 Binder 线程数BinderInternal.setMaxThreads(sMaxBinderThreads);// 准备主线程(当前线程)android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);android.os.Process.setCanSelfBackground(false);Looper.prepareMainLooper();Looper.getMainLooper().setSlowLogThresholdMs(SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);// 启用服务未找到时的 WTF 日志SystemServiceRegistry.sEnableServiceNotFoundWtf = true;// 代码1 初始化本地服务System.loadLibrary("android_servers");// 允许堆和性能分析initZygoteChildHeapProfiling();// 如果是调试版本,启动线程以监控文件描述符泄漏if (Build.IS_DEBUGGABLE) {spawnFdLeakCheckThread();}// 检查上次是否未能正常关闭,此调用可能不会返回performPendingShutdown();// 代码2 初始化系统上下文createSystemContext();// 调用主模块的初始化ActivityThread.initializeMainlineModules();// 代码3 创建系统服务管理器mSystemServiceManager = new SystemServiceManager(mSystemContext);mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);// 准备用于并行化初始化任务的线程池SystemServerInitThreadPool.start();// 如果是调试版本且设置了系统属性,附加 JVMTI 代理if (Build.IS_DEBUGGABLE) {String jvmtiAgent = SystemProperties.get("persist.sys.dalvik.jvmtiagent");if (!jvmtiAgent.isEmpty()) {int equalIndex = jvmtiAgent.indexOf('=');String libraryPath = jvmtiAgent.substring(0, equalIndex);String parameterList = jvmtiAgent.substring(equalIndex + 1, jvmtiAgent.length());try {Debug.attachJvmtiAgent(libraryPath, parameterList, null);} catch (Exception e) {Slog.e("System", "*************************************************");Slog.e("System", "********** Failed to load jvmti plugin: " + jvmtiAgent);}}}} finally {// 结束 "InitBeforeStartServices" 阶段的跟踪t.traceEnd();}// 设置默认的 WTF 处理器RuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf);// 启动服务try {t.traceBegin("StartServices");startBootstrapServices(t); // 代码4 启动引导服务startCoreServices(t); // 代码5 启动核心服务startOtherServices(t); // 代码6 启动其他服务} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;} finally {t.traceEnd(); // 结束 "StartServices" 阶段的跟踪}// 初始化虚拟机的 StrictMode 默认设置StrictMode.initVmDefaults(null);// 如果不是重启且不是首次启动或升级,记录系统服务器启动完成的时间if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {final long uptimeMillis = SystemClock.elapsedRealtime();FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SYSTEM_SERVER_READY,uptimeMillis);final long maxUptimeMillis = 60 * 1000;if (uptimeMillis > maxUptimeMillis) {Slog.wtf(SYSTEM_SERVER_TIMING_TAG,"SystemServer init took too long. uptimeMillis=" + uptimeMillis);}}// 检查运行时是否运行在 boot image 中if (!VMRuntime.hasBootImageSpaces()) {Slog.wtf(TAG, "Runtime is not running with a boot image!");}// 代码7 进入主线程的消息循环Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");
}
run() 方法做的事情:
- System.loadLibrary(“android_servers”); 加载动态库 libandroid_server.so
- createSystemContext(); 创建系统上下文;
- new SystemServiceManager() 创建 SystemServiceManager;
startService() :
(1)反射创建服务,需要一参的构造方法;
(2)执行服务的 onStart() 方法;
(3)返回该服务对象; - startBootstrapServices(t); 启动系统引导服务
(1)ATM 启动
(2)AMS 启动
(3)AMS.setSystemProcess() 将 AMS 等服务添加到 ServiceManager 中
(4)PMS 启动
(5)PKMS 启动 - startCoreServices(t); 启动核心服务
(1)电池服务 - startOtherServices(t); 启动其他服务
(1)WMS 服务
(2)AMS.systemReady() 启动桌面 - Looper.loop 一直循环
3. 系统服务介绍
在 SystemServer 的 run() 方法中可以看到官方把系统服务氛围了三种类型:引导服务、核心服务和其他服务。
系统服务大约有90多个:
- 引导服务 Boot Service(10个):
- 核心服务 Core Service(9个):
- 其他服务 Other Service (70个+):
4. SystemServer 如何管理服务
因为 SystemServer 是系统服务进程,用于管理服务。SystemServiceManager 是管理 Service,所以服务都必须封装 SystemService 这个类。
以启动引导服务为例:
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {...// Activity manager runs the show.t.traceBegin("StartActivityManager");// 启动 Activity 管理器服务(ActivityTaskManagerService 和 ActivityManagerService)ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService(); // 启动 ATMSmActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm); // 启动 AMSmActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);mWindowManagerGlobalLock = atm.getGlobalLock();t.traceEnd();...}
在 startBootstrapServices() 方法中以 AMS 为例,是通过 SystemServiceManager.startService() 来启动的。
接着看一下 SystemServiceManager:
// frameworks/base/services/core/java/com/android/server/SystemServiceManager.javaprivate final ArrayList<SystemService> mServices = new ArrayList<SystemService>();public void startService(@NonNull final SystemService service) {// Register it.// 将 SystemService 添加到 list 中mServices.add(service);// Start it.long time = SystemClock.elapsedRealtime();try {// 启动 SystemServiceservice.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 的 startService() 中,首先将服务添加到集合中,然后启动服务。
总结
SystemServer 在启动时主要做了:
- 启动 bInder 线程池,这样就可以与其他进程进行通信;
- 创建 SystemServiceManager 用于对系统的服务进程创建、启动和生命周期管理;
- 启动各种系统服务;