Android10 启动之SystemServer源码分析
作者:格子里的梦 发布时间:2021-08-15 05:38:13
上一篇文章: # Android 10 启动分析之Zygote篇 (三)
紧接着上一篇文章的内容,我们从这篇文章开始来分析一下 SystemServer。
system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等80多个核心系统服务。这些服务以不同的线程方式存在于system_server这个进程中。
SystemServer的源码路径为 /frameworks/base/services/java/com/android/server/SystemServer.java
,我们从这个类的main方法开始看起:
public static void main(String[] args) {
new SystemServer().run();
}
main方法里创建了一个SystemServer实例,并调用了run方法。SystemServer的构造方法里只是一些简单的变量初始化,我们直接从run方法继续阅读。
private void run() {
try {
...
//准备主线程lopper
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);
// 加载libandroid_servers.so库
System.loadLibrary("android_servers");
//检测上次关机过程是否失败,这个调用可能不会返回
performPendingShutdown();
//初始化系统上下文
createSystemContext();
//创建系统服务管理者--SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
//将mSystemServiceManager添加到本地服务中,至于什么是LocalServices,它有什么作用,
//以后再单独开一篇文章来讲解
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//为可以并行化的init任务准备线程池
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
// 在这里开始启动一系列服务了
try {
traceBeginAndSlog("StartServices");
// 启动引导服务
startBootstrapServices();
// 启动核心服务
startCoreServices();
// 启动其他服务
startOtherServices();
//停止init线程池
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
...
// 死循环执行
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
我们来关注以下几个重点方法:
createSystemContext
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,Instrumentation, ContextImpl,LoadedApk,Application。
为什么会要创建Application对象?就目前的源码来看,Application对象在systemserver进程并无实际作用,笔者只能猜测这是为将来的扩展做准备或者android版本迭代中的历史遗留代码。
startBootstrapServices
在这个方法中会启动系统的关键服务,这些服务是系统运行的基石。因为它们之间具有复杂的依赖关系,所以谷歌把它们放在一起初始化。
private void startBootstrapServices() {
// 尽早启动看门狗,这样我们在早期启动陷入死锁时就可以使system server崩溃重启。
final Watchdog watchdog = Watchdog.getInstance();
watchdog.start();
//启动Installer Service,这个Service 通过binder与installd进程通讯,负责apk安装相关的工作
Installer installer = mSystemServiceManager.startService(Installer.class);
//设备标识符策略服务
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
// 管理uri授权
mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
//启动ActivityTaskManagerService和ActivityManagerService
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
//电源管理器需要尽早启动,因为其他服务需要它。
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
//启动热缓解服务,目的是在手机开始过热时进行有效的热缓解
mSystemServiceManager.startService(ThermalManagerService.class);
// Now that the power manager has been started, let the activity manager
// initialize power management features.
mActivityManagerService.initPowerManagement();
//启动系统恢复服务,负责协调设备上与恢复有关的功能。
mSystemServiceManager.startService(RecoverySystemService.class);
//到这里为止,系统启动的必须服务已经加载完毕
RescueParty.noteBoot(mSystemContext);
//管理LED和屏幕背光,我们需要它来显示
mSystemServiceManager.startService(LightsService.class);
//管理显示设备
//在package manager 启动之前,需要启动display manager 提供display metrics
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
//只有DisplayManagerService会对PHASE_WAIT_FOR_DEFAULT_DISPLAY做处理
//目的是在初始化包管理器之前,首先需要获取一个默认的显示设备
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// 启动 package manager.
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_package_manager_init_start",
(int) SystemClock.elapsedRealtime());
}
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
//启动UserManager Service
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
//为系统进程设置应用程序实例并启动
mActivityManagerService.setSystemProcess();
//使用ActivityManager实例完成看门狗设置并监听是否重启
watchdog.init(mSystemContext, mActivityManagerService);
// DisplayManagerService needs to setup android.display scheduling related policies
// since setSystemProcess() would have overridden policies due to setProcessGroup
mDisplayManagerService.setupSchedulerPolicies();
//负责动态资源overlay
mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));
if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
// DisplayManager needs the overlay immediately.
mActivityManagerService.updateSystemUiContext();
LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
}
//传感器服务需要访问包管理器服务、app ops服务和权限服务,
//因此我们在它们之后启动它。
//在单独的线程中启动传感器服务。在使用它之前应该检查完成情况。
mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(START_SENSOR_SERVICE);
startSensorService();
traceLog.traceEnd();
}, START_SENSOR_SERVICE);
}
总结一下,引导服务有以下15个:
服务名称 | 描述 |
---|---|
Installer | 负责apk安装相关的工作 |
DeviceIdentifiersPolicyService | 设备标识符策略服务 |
UriGrantsManagerService | Uri授权管理 |
ActivityTaskManagerService | 用于管理Activity及其容器(task, stacks, displays,... )的系统服务 |
ActivityManagerService | 管理Activity的启动,调度等工作 |
PowerManagerService | 负责协调设备上的电源管理功能 |
ThermalManagerService | 热缓解服务 |
RecoverySystemService | 负责协调设备上与恢复有关的功能 |
LightsService | 管理LED和屏幕背光 |
DisplayManagerService | 管理显示设备 |
PackageManagerService | 主要负责APK、jar包的管理 |
UserManagerService | 管理用户的系统服务 |
OverlayManagerService | 负责动态资源overlay工作,具体请搜索android RRO技术 |
SensorPrivacyService | 和传感器有关,具体作用不明 |
SensorPrivacySere | 传感器服务 |
startCoreServices
private void startCoreServices() {
// 追踪电池充电状态和电量。需要LightService
mSystemServiceManager.startService(BatteryService.class);
//跟踪应用程序使用状态
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// 跟踪可更新的WebView是否处于就绪状态,并监视更新安装。
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
traceBeginAndSlog("StartWebViewUpdateService");
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
traceEnd();
}
//跟踪并缓存设备状态。
mSystemServiceManager.startService(CachedDeviceStateService.class);
// 跟踪在Binder调用中花费的cpu时间
mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);
// 跟踪handlers中处理messages所花费的时间。
mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
//管理apk回滚
mSystemServiceManager.startService(RollbackManagerService.class);
// 用于捕获bugreport,adb bugreport 命令调用的就是这个服务
mSystemServiceManager.startService(BugreportManagerService.class);
// 管理Gpu和Gpu驱动的服务
mSystemServiceManager.startService(GpuService.class);
}
总结一下,核心服务共计9个:
服务名称 | 描述 |
---|---|
BatteryService | 追踪电池充电状态和电量 |
UsageStatsManagerInternal | 跟踪应用程序使用状态 |
WebViewUpdateService | 跟踪可更新的WebView是否处于就绪状态,并监视更新安装。 |
CachedDeviceStateService | 跟踪并缓存设备状态 |
BinderCallsStatsService | 跟踪在Binder调用中花费的cpu时间 |
LooperStatsService | 跟踪handlers中处理messages所花费的时间。 |
RollbackManagerService | 管理apk回滚 |
BugreportManagerService | 用于捕获bugreport |
GpuService | 管理Gpu和Gpu驱动 |
startOtherServices
这个方法负责启动剩下的服务,共计有70多个,限于篇幅的原因,在此不再一一列举,贴一张从网上找到的图片大家简单的了解一下就行了:
需要注意的是在startOtherServices结尾处调用了AMS的systemReady方法,AMS的systemReady里有这样一条语句:
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
这条语句会启动如下的Intent:
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
注意到Intent.CATEGORY_HOME没,这意味着startHomeOnAllDisplays最终启动的是android的launcher app,android的启动已经进入了结尾。
至此,我们从按下电源键开始,到最终呈现launcher页面,整个启动流程做了一个简单的介绍。Android 10的启动分析系列正篇到此结束,其中启动过程中的一些细节知识点,我们今后再以番外的形式补充介绍,感谢大家的收看!!!
来源:https://juejin.cn/post/7000546993328095262


猜你喜欢
- 使用Convert接口实现类型转换器在Spring3中引入了一个Converter接口,它支持从一个Object转为另一个Object。除了
- 一、为什么需要服务网关:1、什么是服务网关:
- 本文实例为大家分享了java字符串和数字转换工具的具体代码,供大家参考,具体内容如下package com.test.util;/** *
- 现在很多安全类的软件,比如360手机助手,百度手机助手等等,都有一个悬浮窗,可以飘浮在桌面上,方便用户使用一些常用的操作。首先,看一下效果图
- Java中的try-catch-finally异常处理一、异常处理异常(Exception):是在运行发生的不正常情况。原始异常处理:if(
- 最近项目中有截屏的需求,普通的view截屏方法网上一搜一大把,但是SurfaceView截屏黑屏问题很多文章说的并不清楚,自己参考了一些别的
- 本文实例讲述了Android编程实现应用自动更新、下载、安装的方法。分享给大家供大家参考,具体如下:我们看到很多Android应用都具有自动
- 开发Android APP微信支付功能,需要完成三个步骤:第一步生成预支付订单、第二步生成微信支付参数、第三步调起微信APP支付。除了需要审
- 本文实例讲述了Android控件之ListView用法。分享给大家供大家参考。具体如下:示例一:在android开发中ListView是比较
- Android 应用冷启动时,需要从Application开始启动,加载时间就会比较长,容易出现白色或黑色闪屏,观察一下手机上一些 其他AP
- 简介由于最近的项目需求,需要在把配置类导入到容器中,通过查询,使用@Import注解就能实现这个功能,@Import注解能够帮我们吧普通配置
- 今天遇到这样一个bug:客户端POST到服务器的一段数据导致服务器端发生未知异常。服务器端确认是编码转换错误。于是截取网络数据包进行分析,发
- 前言Spring Seuciry相关的内容看了实在是太多了,但总觉得还是理解地不够巩固,还是需要靠知识输出做巩固。相关版本:java: jd
- 本文实例为大家分享了Unity打印机打印图片的具体代码,供大家参考,具体内容如下1、调用打印机首先就是要配置好打印机 就是电脑跟打印机已经连
- jax-ws handler 的详解及简单实例aop技术一般用于某个对象的函数调用的日志,认证等。webservice是远程的函
- 一、Jsoup的主要功能Jsoup是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API
- merge结合include优化android布局,效果不知道,个人感觉使用上也有很大的局限,不过还是了解一下,记录下来。布局文件都要有根节
- 本文实例为大家分享了C#实现飞行棋小游戏的具体代码,供大家参考,具体内容如下逻辑图 以下是掷色子的一个代码,比较有代表性,里面的逻
- 十进制转二进制正整数转二进制除2取余,逆序排列,高位补零。示例:十进制255 = 二进制1111 1111计算过程:255/2=127===
- 一. SpringBoot中实现Session共享1. 创建web项目我们按照之前的经验,创建一个web程序,并将之改造成Spring Bo