Android SystemServer启动过程

背景

这两天有一个需求得联调,在等待服务端同事完事,等待过程中,阅读了一下Android8.0里SystemServer的启动过程,除了设置时区语言这些,其实主要就是初始化了系统上下文以及一些服务的启动。

main()方法

SystemServer是一个进程,由zygote进程fork出来,所以它的入口方法就是main方法,代码如下

 
  1. public static void main(String[] args) {

  2. new SystemServer().run();

  3. }

直接就是new了一个SystemServer,而后执行run()方法

run()方法

方法比较长,代码如下

 
  1. private void run() {

  2. try {

  3. traceBeginAndSlog("InitBeforeStartServices");

  4. // 如果当前系统时间早于1970年元月1号,就更新之为1970年元月1号

  5. if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {

  6. SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);

  7. }

  8.  
  9. // 设置时区

  10. String timezoneProperty = SystemProperties.get("persist.sys.timezone");

  11. if (timezoneProperty == null || timezoneProperty.isEmpty()) {

  12. SystemProperties.set("persist.sys.timezone", "GMT"); // 默认时区是格林尼治时区

  13. }

  14.  
  15. // 设置系统语言

  16. if (!SystemProperties.get("persist.sys.language").isEmpty()) {

  17. final String languageTag = Locale.getDefault().toLanguageTag();

  18.  
  19. SystemProperties.set("persist.sys.locale", languageTag);

  20. SystemProperties.set("persist.sys.language", "");

  21. SystemProperties.set("persist.sys.country", "");

  22. SystemProperties.set("persist.sys.localevar", "");

  23. }

  24.  
  25. // 系统Server不能进行非oneway通信,因为非oneway通信要等待对方的恢复,这个等待过程是阻塞的

  26. Binder.setWarnOnBlocking(true); // 所以设置阻塞时警告

  27.  
  28. // 正式启动SystemServer

  29.  
  30. int uptimeMillis = (int) SystemClock.elapsedRealtime();

  31. EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);

  32. if (!mRuntimeRestart) {

  33. MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);

  34. }

  35.  
  36. // 设置vmLibrary

  37. SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

  38.  
  39. // Enable the sampling profiler.

  40. if (SamplingProfilerIntegration.isEnabled()) {

  41. SamplingProfilerIntegration.start();

  42. mProfilerSnapshotTimer = new Timer();

  43. mProfilerSnapshotTimer.schedule(new TimerTask() {

  44. @Override

  45. public void run() {

  46. SamplingProfilerIntegration.writeSnapshot("system_server", null);

  47. }

  48. }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);

  49. }

  50.  
  51. // 清除内存增长上限,因为加载SystemServer需要很多内存

  52. VMRuntime.getRuntime().clearGrowthLimit();

  53.  
  54. // 设置内存利用率最大是0.8

  55. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

  56.  
  57. // 初始化指纹系统

  58. Build.ensureFingerprintProperty();

  59.  
  60. // 设置访问环境变量(例如sd卡路径等)时,必须指定用户

  61. Environment.setUserRequired(true);

  62.  
  63. // 设置系统的Bundle是可defuse的,意为如果在解析bundle的时候,忽略发生的badParcelableException

  64. // 那个异常如果发送,就直接清空这个Bundle的内容。所以defuse使能最好在Bundle到了终点后再设置,因为这样总不会导致下流再失去bundle的内容

  65. BaseBundle.setShouldDefuse(true);

  66.  
  67. // 保证进入SystemServer的binder都运行在前台

  68. BinderInternal.disableBackgroundScheduling(true);

  69.  
  70. // 设置最大线程数为31

  71. BinderInternal.setMaxThreads(sMaxBinderThreads);

  72.  
  73. // 设置当前线程(主线程)也是在前台进行

  74. android.os.Process.setThreadPriority(

  75. android.os.Process.THREAD_PRIORITY_FOREGROUND);

  76. android.os.Process.setCanSelfBackground(false); // 主线程不能自己切到后台

  77. Looper.prepareMainLooper(); // 主线程的消息循环开始

  78.  
  79. // 加载native服务

  80. System.loadLibrary("android_servers");

  81.  
  82. // 检测上次是否成功关机

  83. performPendingShutdown();

  84.  
  85. // 初始化系统上下文

  86. createSystemContext();

  87.  
  88. // 初始化SysytemServiceManager,并把它添加到LocalServices中

  89. mSystemServiceManager = new SystemServiceManager(mSystemContext);

  90. mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);

  91. LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

  92. // 创建SystemServerInit线程池的单例

  93. SystemServerInitThreadPool.get();

  94. } finally {

  95. traceEnd();

  96. }

  97.  
  98. // 启动一些服务

  99. // Start services.

  100. try {

  101. traceBeginAndSlog("StartServices");

  102. startBootstrapServices(); // 启动引导服务

  103. startCoreServices(); // 启动核心服务

  104. startOtherServices(); // 启动其他服务

  105. SystemServerInitThreadPool.shutdown();

  106. } catch (Throwable ex) {

  107. ...

  108. } finally {

  109. traceEnd();

  110. }

  111.  
  112. ... // 日志

  113.  
  114. // Loop forever.

  115. // 开始消息循环

  116. Looper.loop();

  117. throw new RuntimeException("Main thread loop unexpectedly exited"); // 消息循环是不能退出的

  118. }

代码多但是逻辑并不复杂,值得注意的方法除了启动引导服务、核心服务和其他服务外,再就是检测上次关机是否成功的performPendingShutdown()方法,这个方法主要是针对recovery模式下系统更新引起的重启,这种情况要多重启一次。而这里只是设置了一下sys.powerctl属性,没有执行重启操作

performPendingShutdown()方法

代码如下

 
  1. private void performPendingShutdown() {

  2. final String shutdownAction = SystemProperties.get(

  3. ShutdownThread.SHUTDOWN_ACTION_PROPERTY, ""); // 获取上次的关机信息

  4. if (shutdownAction != null && shutdownAction.length() > 0) {

  5. boolean reboot = (shutdownAction.charAt(0) == '1'); // 关机信息第一位表示关机是否是为了重启

  6.  
  7. final String reason;

  8. if (shutdownAction.length() > 1) {

  9. reason = shutdownAction.substring(1, shutdownAction.length()); // 第一位往后表示关机的原因

  10. } else {

  11. reason = null;

  12. }

  13.  
  14. if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {

  15. /*

  16. * 关机原因是否是REBOOT_RECOVERY_UPDATE,也就是recovery模式下,为了执行系统更新而关的机

  17. * 这种情况下,一定会多重启一次,多的这一次重启,原因就不是REBOOT_RECOVERY_UPDATE了

  18. * @hide

  19.    public static final String REBOOT_RECOVERY_UPDATE = "recovery-update";

  20. */

  21. File packageFile = new File(UNCRYPT_PACKAGE_FILE);

  22. if (packageFile.exists()) {

  23. String filename = null;

  24. try {

  25. filename = FileUtils.readTextFile(packageFile, 0, null); // 读取uncrypt_file的内容,获取的是一个文件名

  26. } catch (IOException e) {

  27. Slog.e(TAG, "Error reading uncrypt package file", e);

  28. }

  29.  
  30. if (filename != null && filename.startsWith("/data")) { // 如果读出来的文件名以/data开头,也就是在data目录内

  31. if (!new File(BLOCK_MAP_FILE).exists()) { // 如果block.map文件不存在,直接抛异常,重启失败

  32. Slog.e(TAG, "Can't find block map file, uncrypt failed or " +

  33. "unexpected runtime restart?");

  34. return;

  35. }

  36. }

  37. }

  38. }

  39. ShutdownThread.rebootOrShutdown(null, reboot, reason);

  40. }

  41. }

主要是调用了ShutdownThread.rebootOrShutdown()方法,这个方法只是保存了一下sys.powerctl属性,代码如下

 
  1. public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {

  2. if (reboot) {

  3. .. // 日志

  4. PowerManagerService.lowLevelReboot(reason);

  5. .. // 日志

  6. reason = null;

  7. } else if (SHUTDOWN_VIBRATE_MS > 0 && context != null) {

  8. // 关机前要进行振动

  9. Vibrator vibrator = new SystemVibrator(context); // 振动器

  10. try {

  11. vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES); // 传入振动持续时间和振动方式

  12. } catch (Exception e) {

  13. .. // 日志

  14. }

  15.  
  16. try {

  17. Thread.sleep(SHUTDOWN_VIBRATE_MS); // 振动是异步的,所以当前线程要阻塞一会儿,保证振动完了,再关机

  18. } catch (InterruptedException unused) {

  19. }

  20. }

  21. // Shutdown power

  22. PowerManagerService.lowLevelShutdown(reason);

如果是进来这个方法是要重启,reboot就是真,先调用PowerManagerService.lowLevelReboot()方法,传入重启原因reason。此方法代码如下

 
  1. public static void lowLevelReboot(String reason) {

  2. if (reason == null) {

  3. reason = "";

  4. }

  5.  
  6. if (reason.equals(PowerManager.REBOOT_QUIESCENT)) {

  7. sQuiescent = true;

  8. reason = "";

  9. } else if (reason.endsWith("," + PowerManager.REBOOT_QUIESCENT)) {

  10. sQuiescent = true;

  11. reason = reason.substring(0,

  12. reason.length() - PowerManager.REBOOT_QUIESCENT.length() - 1);

  13. }

  14.  
  15. if (reason.equals(PowerManager.REBOOT_RECOVERY)

  16. || reason.equals(PowerManager.REBOOT_RECOVERY_UPDATE)) { // 如果reason是或REBOOT_RECOVERY或REBOOT_RECOVERY_UPDATE,就把reason换成recovery

  17. reason = "recovery";

  18. }

  19.  
  20. if (sQuiescent) {

  21. reason = reason + ",quiescent";

  22. }

  23.  
  24. SystemProperties.set("sys.powerctl", "reboot," + reason); // 保存sys.powerctl属性

  25. try {

  26. Thread.sleep(20 * 1000L); // 阻塞20秒

  27. } catch (InterruptedException e) {

  28. Thread.currentThread().interrupt();

  29. }

  30. Slog.wtf(TAG, "Unexpected return from lowLevelReboot!");

  31. }

可以看到,主要是把重启原因进行转换和保存,然后把重启线程阻塞20s。方法执行完后,就会执行lowLevelShutdown(),代码如下

 
  1. public static void lowLevelShutdown(String reason) {

  2. if (reason == null) {

  3. reason = "";

  4. }

  5. SystemProperties.set("sys.powerctl", "shutdown," + reason); // 保存/更新sys.powerctl属性

  6. }

回到SystemServer.run()方法,检测完上次是否正常关机后,调用了createSystemContext()方法获取系统上下文,代码如下

 
  1. private void createSystemContext() {

  2. ActivityThread activityThread = ActivityThread.systemMain();

  3. mSystemContext = activityThread.getSystemContext();

  4. mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

  5.  
  6. final Context systemUiContext = activityThread.getSystemUiContext();

  7. systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);

  8. }

这个方法主要是调用了ActivityThread的一系列方法来实现,参见文章安卓开发学习之获取系统上下文。然后就是调用startBootstrapServices()、startCoreServices()、startOtherServices()方法启动一些服务,以前两个方法为例看一下代码

startBootstrapServices()方法

启动一些引导服务,代码如下

 
  1. private void startBootstrapServices() {

  2.  
  3. // 创建SystemConfig,进行权限的获取

  4. SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);

  5.  
  6. // 开启安装器服务

  7. Installer installer = mSystemServiceManager.startService(Installer.class);

  8.  
  9. // 设备识别器服务

  10. mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);

  11.  
  12. // 启动并初始化ActivityManagerService

  13. mActivityManagerService = mSystemServiceManager.startService(

  14. ActivityManagerService.Lifecycle.class).getService();

  15. mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

  16. mActivityManagerService.setInstaller(installer);

  17.  
  18. // 启动电量管理服务

  19. mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

  20.  
  21. // 初始化电量管理器

  22. mActivityManagerService.initPowerManagement();

  23.  
  24. if (!SystemProperties.getBoolean("config.disable_noncore", false)) {

  25. traceBeginAndSlog("StartRecoverySystemService");

  26. // 启动RecoverySystem服务

  27. mSystemServiceManager.startService(RecoverySystemService.class);

  28. }

  29.  
  30. // 标记裸机已经启动完了,如果我们困在了运行时的重启循环中,这个标记可以跳出这个循环

  31. RescueParty.noteBoot(mSystemContext);

  32.  
  33. // 启动灯光服务,包括背景亮度、闪光灯等

  34. mSystemServiceManager.startService(LightsService.class);

  35.  
  36. // 启动显示服务,用来显示UI

  37. mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

  38.  
  39. // 开始开机动画

  40. mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

  41.  
  42. // 加密模式下,只运行内核应用,此处先设置标志位

  43. String cryptState = SystemProperties.get("vold.decrypt");

  44. if (ENCRYPTING_STATE.equals(cryptState)) {

  45. mOnlyCore = true;

  46. } else if (ENCRYPTED_STATE.equals(cryptState)) {

  47. mOnlyCore = true;

  48. }

  49.  
  50. // 开启包管理器服务

  51. mPackageManagerService = PackageManagerService.main(mSystemContext, installer,

  52. mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

  53. mFirstBoot = mPackageManagerService.isFirstBoot();

  54. // 获取包管理器

  55. mPackageManager = mSystemContext.getPackageManager();

  56.  
  57. if (!mOnlyCore) {

  58. boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",

  59. false);

  60. if (!disableOtaDexopt) {

  61. try {

  62. // OTADexOpt(空中下载dex并优化,用于OTA升级)使能时,启动OTA升级服务

  63. OtaDexoptService.main(mSystemContext, mPackageManagerService);

  64. } catch (Throwable e) {

  65. ..

  66. } finally {

  67.                    ..      

  68. }

  69. }

  70. }

  71.  
  72. // 启动用户管理服务

  73. mSystemServiceManager.startService(UserManagerService.LifeCycle.class);

  74.  
  75. traceBeginAndSlog("InitAttributerCache");

  76. // 从系统包中初始化属性资源

  77. AttributeCache.init(mSystemContext);

  78.  
  79. // 设置系统进程

  80. mActivityManagerService.setSystemProcess();

  81.  
  82. // 设置ui的调度策略

  83. mDisplayManagerService.setupSchedulerPolicies();

  84.  
  85. // 启动OverlayManagerService,用于定制系统界面

  86. mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));

  87.  
  88. // 开启传感器服务

  89. mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {

  90. BootTimingsTraceLog traceLog = new BootTimingsTraceLog(

  91. SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);

  92. traceLog.traceBegin(START_SENSOR_SERVICE);

  93. startSensorService();

  94. traceLog.traceEnd();

  95. }, START_SENSOR_SERVICE);

  96. }

开启了一些服务,无需多解释

startCoreServices()方法

也是启动一些服务,代码如下

 
  1. private void startCoreServices() {

  2.  
  3. // 启动DropBox服务,用来记录系统日志

  4. mSystemServiceManager.startService(DropBoxManagerService.class);

  5.  
  6. // 启动电池服务

  7. mSystemServiceManager.startService(BatteryService.class);

  8.  
  9. traceBeginAndSlog("StartUsageService");

  10. // 启动使用状态服务

  11. mSystemServiceManager.startService(UsageStatsService.class);

  12. mActivityManagerService.setUsageStatsManager(

  13. LocalServices.getService(UsageStatsManagerInternal.class));

  14. // 启动WebView更新服务

  15. mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);

  16. }

结语

SystemService的启动过程就是如此,主要还是启动一些服务

原文地址:https://blog.csdn.net/qq_37475168/article/details/80903762

猜你喜欢

转载自blog.csdn.net/f2006116/article/details/81866286