赞
踩
这两天有一个需求得联调,在等待服务端同事完事,等待过程中,阅读了一下Android8.0里SystemServer的启动过程,除了设置时区语言这些,其实主要就是初始化了系统上下文以及一些服务的启动。
SystemServer是一个进程,由zygote进程fork出来,所以它的入口方法就是main方法,代码如下
- public static void main(String[] args) {
- new SystemServer().run();
- }
直接就是new了一个SystemServer,而后执行run()方法
方法比较长,代码如下
- private void run() {
- try {
- traceBeginAndSlog("InitBeforeStartServices");
- // 如果当前系统时间早于1970年元月1号,就更新之为1970年元月1号
- if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
- SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
- }
-
- // 设置时区
- String timezoneProperty = SystemProperties.get("persist.sys.timezone");
- if (timezoneProperty == null || timezoneProperty.isEmpty()) {
- SystemProperties.set("persist.sys.timezone", "GMT"); // 默认时区是格林尼治时区
- }
-
- // 设置系统语言
- 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", "");
- }
-
- // 系统Server不能进行非oneway通信,因为非oneway通信要等待对方的恢复,这个等待过程是阻塞的
- Binder.setWarnOnBlocking(true); // 所以设置阻塞时警告
-
- // 正式启动SystemServer
-
- int uptimeMillis = (int) SystemClock.elapsedRealtime();
- EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
- if (!mRuntimeRestart) {
- MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
- }
-
- // 设置vmLibrary
- SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
-
- // Enable the sampling profiler.
- if (SamplingProfilerIntegration.isEnabled()) {
- SamplingProfilerIntegration.start();
- mProfilerSnapshotTimer = new Timer();
- mProfilerSnapshotTimer.schedule(new TimerTask() {
- @Override
- public void run() {
- SamplingProfilerIntegration.writeSnapshot("system_server", null);
- }
- }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
- }
-
- // 清除内存增长上限,因为加载SystemServer需要很多内存
- VMRuntime.getRuntime().clearGrowthLimit();
-
- // 设置内存利用率最大是0.8
- VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
-
- // 初始化指纹系统
- Build.ensureFingerprintProperty();
-
- // 设置访问环境变量(例如sd卡路径等)时,必须指定用户
- Environment.setUserRequired(true);
-
- // 设置系统的Bundle是可defuse的,意为如果在解析bundle的时候,忽略发生的badParcelableException
- // 那个异常如果发送,就直接清空这个Bundle的内容。所以defuse使能最好在Bundle到了终点后再设置,因为这样总不会导致下流再失去bundle的内容
- BaseBundle.setShouldDefuse(true);
-
- // 保证进入SystemServer的binder都运行在前台
- BinderInternal.disableBackgroundScheduling(true);
-
- // 设置最大线程数为31
- BinderInternal.setMaxThreads(sMaxBinderThreads);
-
- // 设置当前线程(主线程)也是在前台进行
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_FOREGROUND);
- android.os.Process.setCanSelfBackground(false); // 主线程不能自己切到后台
- Looper.prepareMainLooper(); // 主线程的消息循环开始
-
- // 加载native服务
- System.loadLibrary("android_servers");
-
- // 检测上次是否成功关机
- performPendingShutdown();
-
- // 初始化系统上下文
- createSystemContext();
-
- // 初始化SysytemServiceManager,并把它添加到LocalServices中
- mSystemServiceManager = new SystemServiceManager(mSystemContext);
- mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
- LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
- // 创建SystemServerInit线程池的单例
- SystemServerInitThreadPool.get();
- } finally {
- traceEnd();
- }
-
- // 启动一些服务
- // Start services.
- try {
- traceBeginAndSlog("StartServices");
- startBootstrapServices(); // 启动引导服务
- startCoreServices(); // 启动核心服务
- startOtherServices(); // 启动其他服务
- SystemServerInitThreadPool.shutdown();
- } catch (Throwable ex) {
- ...
- } finally {
- traceEnd();
- }
-
- ... // 日志
-
- // Loop forever.
- // 开始消息循环
- Looper.loop();
- throw new RuntimeException("Main thread loop unexpectedly exited"); // 消息循环是不能退出的
- }
代码多但是逻辑并不复杂,值得注意的方法除了启动引导服务、核心服务和其他服务外,再就是检测上次关机是否成功的performPendingShutdown()方法,这个方法主要是针对recovery模式下系统更新引起的重启,这种情况要多重启一次。而这里只是设置了一下sys.powerctl属性,没有执行重启操作
代码如下
- private void performPendingShutdown() {
- final 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;
- }
-
- if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {
- /*
- * 关机原因是否是REBOOT_RECOVERY_UPDATE,也就是recovery模式下,为了执行系统更新而关的机
- * 这种情况下,一定会多重启一次,多的这一次重启,原因就不是REBOOT_RECOVERY_UPDATE了
- * @hide
- public static final String REBOOT_RECOVERY_UPDATE = "recovery-update";
- */
- File packageFile = new File(UNCRYPT_PACKAGE_FILE);
- if (packageFile.exists()) {
- String filename = null;
- try {
- filename = FileUtils.readTextFile(packageFile, 0, null); // 读取uncrypt_file的内容,获取的是一个文件名
- } catch (IOException e) {
- Slog.e(TAG, "Error reading uncrypt package file", e);
- }
-
- if (filename != null && filename.startsWith("/data")) { // 如果读出来的文件名以/data开头,也就是在data目录内
- if (!new File(BLOCK_MAP_FILE).exists()) { // 如果block.map文件不存在,直接抛异常,重启失败
- Slog.e(TAG, "Can't find block map file, uncrypt failed or " +
- "unexpected runtime restart?");
- return;
- }
- }
- }
- }
- ShutdownThread.rebootOrShutdown(null, reboot, reason);
- }
- }
主要是调用了ShutdownThread.rebootOrShutdown()方法,这个方法只是保存了一下sys.powerctl属性,代码如下
- public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
- if (reboot) {
- .. // 日志
- PowerManagerService.lowLevelReboot(reason);
- .. // 日志
- reason = null;
- } else if (SHUTDOWN_VIBRATE_MS > 0 && context != null) {
- // 关机前要进行振动
- Vibrator vibrator = new SystemVibrator(context); // 振动器
- try {
- vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES); // 传入振动持续时间和振动方式
- } catch (Exception e) {
- .. // 日志
- }
-
- try {
- Thread.sleep(SHUTDOWN_VIBRATE_MS); // 振动是异步的,所以当前线程要阻塞一会儿,保证振动完了,再关机
- } catch (InterruptedException unused) {
- }
- }
- // Shutdown power
- PowerManagerService.lowLevelShutdown(reason);
如果是进来这个方法是要重启,reboot就是真,先调用PowerManagerService.lowLevelReboot()方法,传入重启原因reason。此方法代码如下
- public static void lowLevelReboot(String reason) {
- if (reason == null) {
- reason = "";
- }
-
- if (reason.equals(PowerManager.REBOOT_QUIESCENT)) {
- sQuiescent = true;
- reason = "";
- } else if (reason.endsWith("," + PowerManager.REBOOT_QUIESCENT)) {
- sQuiescent = true;
- reason = reason.substring(0,
- reason.length() - PowerManager.REBOOT_QUIESCENT.length() - 1);
- }
-
- if (reason.equals(PowerManager.REBOOT_RECOVERY)
- || reason.equals(PowerManager.REBOOT_RECOVERY_UPDATE)) { // 如果reason是或REBOOT_RECOVERY或REBOOT_RECOVERY_UPDATE,就把reason换成recovery
- reason = "recovery";
- }
-
- if (sQuiescent) {
- reason = reason + ",quiescent";
- }
-
- SystemProperties.set("sys.powerctl", "reboot," + reason); // 保存sys.powerctl属性
- try {
- Thread.sleep(20 * 1000L); // 阻塞20秒
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- Slog.wtf(TAG, "Unexpected return from lowLevelReboot!");
- }
可以看到,主要是把重启原因进行转换和保存,然后把重启线程阻塞20s。方法执行完后,就会执行lowLevelShutdown(),代码如下
- public static void lowLevelShutdown(String reason) {
- if (reason == null) {
- reason = "";
- }
- SystemProperties.set("sys.powerctl", "shutdown," + reason); // 保存/更新sys.powerctl属性
- }
回到SystemServer.run()方法,检测完上次是否正常关机后,调用了createSystemContext()方法获取系统上下文,代码如下
- private void createSystemContext() {
- ActivityThread activityThread = ActivityThread.systemMain();
- mSystemContext = activityThread.getSystemContext();
- mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
-
- final Context systemUiContext = activityThread.getSystemUiContext();
- systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
- }
这个方法主要是调用了ActivityThread的一系列方法来实现,参见文章
安卓开发学习之获取系统上下文。然后就是调用startBootstrapServices()、startCoreServices()、startOtherServices()方法启动一些服务,以前两个方法为例看一下代码
启动一些引导服务,代码如下
- private void startBootstrapServices() {
-
- // 创建SystemConfig,进行权限的获取
- SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
-
- // 开启安装器服务
- Installer installer = mSystemServiceManager.startService(Installer.class);
-
- // 设备识别器服务
- mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
-
- // 启动并初始化ActivityManagerService
- mActivityManagerService = mSystemServiceManager.startService(
- ActivityManagerService.Lifecycle.class).getService();
- mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
- mActivityManagerService.setInstaller(installer);
-
- // 启动电量管理服务
- mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
-
- // 初始化电量管理器
- mActivityManagerService.initPowerManagement();
-
- if (!SystemProperties.getBoolean("config.disable_noncore", false)) {
- traceBeginAndSlog("StartRecoverySystemService");
- // 启动RecoverySystem服务
- mSystemServiceManager.startService(RecoverySystemService.class);
- }
-
- // 标记裸机已经启动完了,如果我们困在了运行时的重启循环中,这个标记可以跳出这个循环
- RescueParty.noteBoot(mSystemContext);
-
- // 启动灯光服务,包括背景亮度、闪光灯等
- mSystemServiceManager.startService(LightsService.class);
-
- // 启动显示服务,用来显示UI
- mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
-
- // 开始开机动画
- mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
-
- // 加密模式下,只运行内核应用,此处先设置标志位
- String cryptState = SystemProperties.get("vold.decrypt");
- if (ENCRYPTING_STATE.equals(cryptState)) {
- mOnlyCore = true;
- } else if (ENCRYPTED_STATE.equals(cryptState)) {
- mOnlyCore = true;
- }
-
- // 开启包管理器服务
- mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
- mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
- mFirstBoot = mPackageManagerService.isFirstBoot();
- // 获取包管理器
- mPackageManager = mSystemContext.getPackageManager();
-
- if (!mOnlyCore) {
- boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
- false);
- if (!disableOtaDexopt) {
- try {
- // OTADexOpt(空中下载dex并优化,用于OTA升级)使能时,启动OTA升级服务
- OtaDexoptService.main(mSystemContext, mPackageManagerService);
- } catch (Throwable e) {
- ..
- } finally {
- ..
- }
- }
- }
-
- // 启动用户管理服务
- mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
-
- traceBeginAndSlog("InitAttributerCache");
- // 从系统包中初始化属性资源
- AttributeCache.init(mSystemContext);
-
- // 设置系统进程
- mActivityManagerService.setSystemProcess();
-
- // 设置ui的调度策略
- mDisplayManagerService.setupSchedulerPolicies();
-
- // 启动OverlayManagerService,用于定制系统界面
- mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
-
- // 开启传感器服务
- mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
- BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
- SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
- traceLog.traceBegin(START_SENSOR_SERVICE);
- startSensorService();
- traceLog.traceEnd();
- }, START_SENSOR_SERVICE);
- }
开启了一些服务,无需多解释
也是启动一些服务,代码如下
- private void startCoreServices() {
-
- // 启动DropBox服务,用来记录系统日志
- mSystemServiceManager.startService(DropBoxManagerService.class);
-
- // 启动电池服务
- mSystemServiceManager.startService(BatteryService.class);
-
- traceBeginAndSlog("StartUsageService");
- // 启动使用状态服务
- mSystemServiceManager.startService(UsageStatsService.class);
- mActivityManagerService.setUsageStatsManager(
- LocalServices.getService(UsageStatsManagerInternal.class));
- // 启动WebView更新服务
- mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
- }
SystemService的启动过程就是如此,主要还是启动一些服务
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。