Zygote家的大兒子——SystemServer

本文基於 Android 9.0 , 代碼倉庫地址 : https://github.com/lulululbj/android_9.0.0_r45

文中源碼鏈接:

https://github.com/lulululbj/android_9.0.0_r45/blob/master/frameworks/base/services/java/com/android/server/SystemServer.java

https://github.com/lulululbj/android_9.0.0_r45/blob/master/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

https://github.com/lulululbj/android_9.0.0_r45/blob/master/frameworks/base/services/core/java/com/android/server/SystemService.java

首先來回顧一下上篇文章 https://juejin.im/post/5d8f73bf51882555b149dc64 ,主要介紹了 Android 世界中的第一個 Java 進程 Zygote,它的主要工作流程如下:

registerServerSocketFromEnv(), 註冊服務端 socket,用於和客戶端進程通信preload(),預加載一系列資源,提高應用啟動速度forkSystemServer(),創建 system_server 進程功成身退,調用 runSelectLoop() 等待響應客戶端請求,創建應用進程

本篇文章的主角 system_server 進程是 Zygote 進程 fork 出的第一個進程,它負責管理和啟動整個 Framework 層。

再來看看 http://gityuan.com 的這張圖片,找一下 System Server 的位置,它承載了各類系統服務的創建和啟動。關於 system_server 進程的創建流程,上篇文章中已經做了詳細介紹,這裡再簡單看一下流程圖:

最終會調用到 SystemServer.main() 方法。下面就以此為起點,來具體分析 SystemServer 都做了些什麼。

SystemServer 啟動流程

public static void main(String[] args) { new SystemServer().run(); }

接著看 run() 方法。

private void run() { try { ...... // 如果設備時間早於 1970 年,很多 API 處理負數時會 crash。所以直接設置為 1970 年 1 月 1 日 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } // 未設置時區的話默認設為 GMT String 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"); } // 語言地區設置 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", ""); } // The system server should never make non-oneway calls Binder.setWarnOnBlocking(true); // The system server should always load safe labels PackageItemInfo.setForceSafeLabels(true); // Default to FULL within the system server. SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL; // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized SQLiteCompatibilityWalFlags.init(null); // Here we go! Slog.i(TAG, "Entered the Android system server!"); int uptimeMillis = (int) SystemClock.elapsedRealtime(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis); if (!mRuntimeRestart) { MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis); } // 設置虛擬機運行庫路徑 SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); // Mmmmmm... more memory! // 清除虛擬機內存增長限制,允許應用申請更多內存 VMRuntime.getRuntime().clearGrowthLimit(); // 設置堆內存的有效利用率為 0.8,(可能被忽略) VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // 確保指紋信息已經定義 Build.ensureFingerprintProperty(); // Within the system server, it is an error to access Environment paths without // explicitly specifying a user. Environment.setUserRequired(true); // Within the system server, any incoming Bundles should be defused // to avoid throwing BadParcelableException. BaseBundle.setShouldDefuse(true); // Within the system server, when parceling exceptions, include the stack trace Parcel.setStackTraceParceling(true); // 確保系統的 Binder 調用總是運行在前臺優先級 BinderInternal.disableBackgroundScheduling(true); // Increase the number of binder threads in system_server BinderInternal.setMaxThreads(sMaxBinderThreads); // Prepare the main looper thread (this thread). android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); // 1. 創建主線程 Looper Looper.prepareMainLooper(); Looper.getMainLooper().setSlowLogThresholdMs( SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); // 初始化 native 服務,加載 libandroid_servers.so System.loadLibrary("android_servers"); // 檢查上次關機是否失敗,可能不會有返回值 performPendingShutdown(); // 2. 初始化系統上下文 createSystemContext(); // 3. 創建系統服務管理 SystemServiceManager // 並將 mSystemServiceManager 註冊到 sLocalServiceObjects 中 mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Prepare the thread pool for init tasks that can be parallelized SystemServerInitThreadPool.get(); } finally { traceEnd(); // InitBeforeStartServices } // Start services. try { traceBeginAndSlog("StartServices"); startBootstrapServices(); // 4. 啟動系統引導服務 startCoreServices(); // 5. 啟動系統核心服務 startOtherServices(); // 6. 啟動其他服務 SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); } StrictMode.initVmDefaults(null); if (!mRuntimeRestart && !isFirstBootOrUpgrade()) { int uptimeMillis = (int) SystemClock.elapsedRealtime(); MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis); final int MAX_UPTIME_MILLIS = 60 * 1000; if (uptimeMillis > MAX_UPTIME_MILLIS) { Slog.wtf(SYSTEM_SERVER_TIMING_TAG, "SystemServer init took too long. uptimeMillis=" + uptimeMillis); } } // 7. Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }

代碼雖然比較長,但是邏輯很清晰。我在註釋裡標記了比較重要的 7 個步驟,逐一分析。

Looper.prepareMainLooper()

初始化 Looper。關於 Handler 消息機制,可以閱讀我的另一篇文章 https://juejin.im/post/5d712cedf265da03ea5a9ecf 。最後會調用 Looper.loop() 開啟消息循環,開始處理消息。

createSystemContext()

private void createSystemContext() { // 創建 system_server 上下文信息 ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); final Context systemUiContext = activityThread.getSystemUiContext(); // 設置主題,用於系統 dialog 等 systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); }

創建系統上下文。首先調用 ActivityThread.systemMain() 方法獲取 ActivityThread 對象,然後再獲取上下文。

public static ActivityThread systemMain() { // 判斷是否是大內存設備,在低內存設備上不啟用硬件加速 if (!ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true); } else { ThreadedRenderer.enableForegroundTrimming(); } ActivityThread thread = new ActivityThread(); thread.attach(true, 0); return thread; }

關於 ActivityThread.attach() 方法這裡不做具體分析了,後面文章說到應用啟動時再來詳細解析。

創建完系統上下文,接下來就是啟動各種系統服務了。源碼中把服務大致分為了三類,再來回顧一下:

startBootstrapServices(); // 4. 啟動系統引導服務 startCoreServices(); // 5. 啟動系統核心服務 startOtherServices(); // 6. 啟動其他服務

逐一進行分析。

startBootstrapServices()

private void startBootstrapServices() { final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig"; SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG); // 阻塞等待與 installd 建立 socket 通道 Installer installer = mSystemServiceManager.startService(Installer.class); // 啟動 DeviceIdentifiersPolicyService,在 ActivityManagerService 之前 mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class); // 啟動服務 ActivityManagerService mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); // 啟動服務 PowerManagerService mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); // Now that the power manager has been started, let the activity manager // initialize power management features. mActivityManagerService.initPowerManagement(); // 啟動服務 RecoverySystemService mSystemServiceManager.startService(RecoverySystemService.class); // Now that we have the bare essentials of the OS up and running, take // note that we just booted, which might send out a rescue party if // we're stuck in a runtime restart loop. RescueParty.noteBoot(mSystemContext); // 啟動服務 LightsService mSystemServiceManager.startService(LightsService.class); // Package manager isn't started yet; need to use SysProp not hardware feature if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) { mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS); } // 啟動 DisplayManagerService,在 PackageManagerService 之前 mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); // We need the default display before we can initialize the package manager. mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); // 正在加密設備時只運行核心 app String cryptState = SystemProperties.get("vold.decrypt"); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; } else if (ENCRYPTED_STATE.equals(cryptState)) { Slog.w(TAG, "Device encrypted - only parsing core apps"); mOnlyCore = true; } // 啟動服務 PackageManagerService if (!mRuntimeRestart) { MetricsLogger.histogram(null, "boot_package_manager_init_start", (int) SystemClock.elapsedRealtime()); } mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); if (!mRuntimeRestart && !isFirstBootOrUpgrade()) { MetricsLogger.histogram(null, "boot_package_manager_init_ready", (int) SystemClock.elapsedRealtime()); } if (!mOnlyCore) { boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { traceBeginAndSlog("StartOtaDexOptService"); try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { reportWtf("starting OtaDexOptService", e); } finally { traceEnd(); } } } // 啟動服務 UserManagerService mSystemServiceManager.startService(UserManagerService.LifeCycle.class); // 初始化屬性 cache 以緩存包資源 AttributeCache.init(mSystemContext); // 設置 AMS mActivityManagerService.setSystemProcess(); // DisplayManagerService needs to setup android.display scheduling related policies // since setSystemProcess() would have overridden policies due to setProcessGroup mDisplayManagerService.setupSchedulerPolicies(); // 啟動服務 OverlayManagerService OverlayManagerService overlayManagerService = new OverlayManagerService( mSystemContext, installer); mSystemServiceManager.startService(overlayManagerService); if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) { // DisplayManager needs the overlay immediately. overlayManagerService.updateSystemUiContext(); LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged(); } // 在單獨的線程中啟動 SensorService mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> { TimingsTraceLog traceLog = new TimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); startSensorService(); }, START_SENSOR_SERVICE); }

startBootstrapServices() 方法中的都是系統啟動過程中的關鍵服務,且相互依賴,主要下列服務 :

Installer DeviceIdentifiersPolicyService ActivityManagerService PowerManagerService RecoverySystemService LightsService StartSidekickService DisplayManagerService

SystemService.PHASEWAITFORDEFAULTDISPLAY (100)

PackageManagerService UserManagerService OverlayManagerService SensorService

一共啟動了十二個核心服務。注意中間的 SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY,它並不是代表什麼系統服務,而是一個 int 值 100,類似的 int 值還有一些,定義在 SystemService 類中,它的作用是給服務啟動過程劃分階段,每個階段都有特定的含義,可以做不同的事情。這裡先混個臉熟,等介紹完所有的服務,再回過頭來總結一下有哪些階段。

startCoreServices()

private void startCoreServices() { // 啟動服務 BatteryService,需要 LightService mSystemServiceManager.startService(BatteryService.class); // 啟動服務 UsageStatsService,統計應用使用情況 mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); // 檢查是否存在可更新的 WebView。存在就啟動服務 WebViewUpdateService if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) { mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class); } // 啟動服務 BinderCallsStatsService,跟蹤 Binder 調用的 cpu 時間消耗 BinderCallsStatsService.start(); }

啟動了四個服務,BatteryService UsageStatsService WebViewUpdateService 和 BinderCallsStatsService 。

startOtherServices()

startOtherServices() 源碼有一千多行,就像一個雜貨鋪,啟動了一系列的服務。下面儘量精簡一下代碼:

KeyAttestationApplicationIdProviderService/KeyChainSystemService SchedulingPolicyService/TelecomLoaderService/TelephonyRegistry mContentResolver = context.getContentResolver(); AccountManagerService/ContentService mActivityManagerService.installSystemProviders(); DropBoxManagerService/VibratorService/ConsumerIrService/AlarmManagerService final Watchdog watchdog = Watchdog.getInstance(); watchdog.init(context, mActivityManagerService); InputManagerService/WindowManagerService/VrManagerService/BluetoothService IpConnectivityMetrics/NetworkWatchlistService/PinnerService InputMethodManagerService/AccessibilityManagerService/StorageManagerService StorageStatsService/UiModeManagerService/LockSettingsService PersistentDataBlockService/OemLockService/DeviceIdleController DevicePolicyManagerService/StatusBarManagerService/ClipboardService NetworkManagementService/IpSecService/TextServicesManagerService TextClassificationManagerService/NetworkScoreService/NetworkStatsService NetworkPolicyManagerService/WifiScanningService/RttService WifiAware/WifiP2P/Lowpan/Ethernet/ConnectivityService/NsdService SystemUpdateManagerService/UpdateLockService/NotificationManagerService DeviceStorageMonitorService/LocationManagerService/CountryDetectorService SearchManagerService/WallpaperManagerService/AudioService/BroadcastRadioService DockObserver/ThermalObserver/WiredAccessoryManager/MidiManager/UsbService SerialService/HardwarePropertiesManagerService/TwilightService ColorDisplayService/JobSchedulerService/SoundTriggerService/TrustManagerService BackupManager/AppWidgerService/VoiceRecognitionManager/GestureLauncherService SensorNotificationService/ContextHubSystemService/DiskStatsService TimeZoneRulesManagerService/NetworkTimeUpdateService/CommonTimeManagementService CertBlacklister/EmergencyAffordanceService/DreamManagerService/GraphicsStatsService CoverageService/PrintManager/CompanionDeviceManager/RestrictionsManagerService MediaSessionService/MediaUpdateService/HdmiControlService/TvInputManagerService MediaResourceMonitorService/TvRemoteService/MediaRouterService/FingerprintService BackgroundDexOptService/PruneInstantAppsJobService/ShortcutService LauncherAppsService/CrossProfileAppsService/MediaProjectionManagerService WearConfigService/WearConnectivityService/WearTimeService/WearLeftyService WearGlobalActionsService/SliceManagerService/CameraServiceProxy/IoTSystemService MmsServiceBroker/AutoFillService // It is now time to start up the app processes... vibrator.systemReady(); lockSettings.systemReady(); // 480 mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); // 500 mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); wm.systemReady(); mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService()); mPackageManagerService.systemReady(); mDisplayManagerService.systemReady(safeMode, mOnlyCore); // Start device specific services final String[] classes = mSystemContext.getResources().getStringArray( R.array.config_deviceSpecificSystemServices); for (final String className : classes) { try { mSystemServiceManager.startService(className); } catch (Throwable e) { reportWtf("starting " + className, e); } } // 520 mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY); mActivityManagerService.systemReady(() -> { // 550 mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY); startSystemUi(context, windowManagerF); networkManagementF.systemReady(); ipSecServiceF.systemReady(); networkStatsF.systemReady(); connectivityF.systemReady(); Watchdog.getInstance().start mPackageManagerService.waitForAppDataPrepared(); // 600 mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); locationF.systemRunning(); countryDetectorF.systemRunning(); networkTimeUpdaterF.systemRunning(); commonTimeMgmtServiceF.systemRunning(); inputManagerF.systemRunning(); telephonyRegistryF.systemRunning(); mediaRouterF.systemRunning(); mmsServiceF.systemRunning(); incident.systemRunning(); }

通過上面的代碼可以看到啟動了相當多的系統服務。startOtherServices() 方法共經歷了五個啟動階段,如下所示:

SystemService.PHASE_LOCK_SETTINGS_READY // 480 SystemService.PHASE_SYSTEM_SERVICES_READY // 500 SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY // 520 SystemService.PHASE_ACTIVITY_MANAGER_READY // 550 SystemService.PHASE_THIRD_PARTY_APPS_CAN_START // 600

最後調用的 mActivityManagerService.systemReady() 方法。該方法中會調用 startHomeActivityLocked 來啟動桌面 Activity,這樣桌面應用就啟動了。

Looper.loop()

至此,system_server 進程的主要工作就算完成了,進入 Looper.loop() 狀態,等待其他線程通過 Handler 發送消息到主線程並處理。

SystemServer 啟動階段分類

回過頭再來看看前面提到的啟動階段分類,定義在 com.android.server.SystemService 類中:

/* * Boot Phases * * 啟動階段 */ public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency? /** * After receiving this boot phase, services can obtain lock settings data. */ public static final int PHASE_LOCK_SETTINGS_READY = 480; /** * After receiving this boot phase, services can safely call into core system services * such as the PowerManager or PackageManager. * * 在這個階段之後,可以安全的調用系統核心服務,如 PowerManager 和 PackageManager */ public static final int PHASE_SYSTEM_SERVICES_READY = 500; /** * After receiving this boot phase, services can safely call into device specific services. * * 在這個階段之後,可以安全調用設備特定的服務 */ public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520; /** * After receiving this boot phase, services can broadcast Intents. * * 在這個階段之後,服務可以廣播 */ public static final int PHASE_ACTIVITY_MANAGER_READY = 550; /** * After receiving this boot phase, services can start/bind to third party apps. * Apps will be able to make Binder calls into services at this point. * * 在這個階段之後,服務可以啟動/綁定第三方應用 * 應用此時可以進行 Binder 調用 */ public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; /** * After receiving this boot phase, services can allow user interaction with the device. * This phase occurs when boot has completed and the home application has started. * System services may prefer to listen to this phase rather than registering a * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency. * * 在這個階段之後,允許用戶和設備交互。 * 這個階段發生在啟動完成,home 應用已經開始。 * 系統服務更傾向於監聽這個階段,而不是監聽啟動廣播 ACTION_BOOT_COMPLETED,以降低延遲 */ public static final int PHASE_BOOT_COMPLETED = 1000;

在 system_server 啟動過程中各個階段的位置大致如下:

private void startBootstrapServices() { ... // 100 mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); ... } private void startOtherServices() { ... // 480 mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); // 500 mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); ... // 520 mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY); mActivityManagerService.systemReady(() -> { mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); // 550 ... mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); // 600 } }

最後的 SystemService.PHASE_BOOT_COMPLETED(1000) 在 AMS 的 finishBooting() 方法中調用。另外注意 480 和 500 兩個階段是連在一起的,中間沒有發生任何事情。

那麼,劃分階段的具體作用是什麼呢?答案就在 startBootPhase() 方法中:

public void startBootPhase(final int phase) { if (phase <= mCurrentPhase) { throw new IllegalArgumentException("Next phase must be larger than previous"); } mCurrentPhase = phase; try { final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); long time = SystemClock.elapsedRealtime(); try { // 回調系統服務的 onBootPhase() 方法 service.onBootPhase(mCurrentPhase); } catch (Exception ex) { throw new RuntimeException("Failed to boot service " + service.getClass().getName() + ": onBootPhase threw an exception during phase " + mCurrentPhase, ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase"); } } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } }

核心就在於 service.onBootPhase(mCurrentPhase);。所有系統服務都是繼承於 SystemService 的,startBootPhase() 方法會回調當前階段已經加入 mServices 的所有系統服務的 onBootPhase() 方法,在合適的階段做一些合適的事情。以 AMS 為例:

@Override public void onBootPhase(int phase) { mService.mBootPhase = phase; if (phase == PHASE_SYSTEM_SERVICES_READY) { mService.mBatteryStatsService.systemServicesReady(); mService.mServices.systemServicesReady(); } }

SystemServer 是如何啟動服務的 ?

看完 SystemServer 的源碼,它最重要的工作就是創建和啟動各種系統服務。那麼服務一般是如何創建的呢?下面以 startBootstrapServices() 中創建的第一個服務 Installer 為例來看一下:

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

進入 SystemServiceManager 的 startService() 方法:

public T startService(Class serviceClass) { try { // 獲取服務名稱 final String name = serviceClass.getName(); // Create the service. if (!SystemService.class.isAssignableFrom(serviceClass)) { throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName()); } final T service; try { // 獲取服務類的構造器 Constructor constructor = serviceClass.getConstructor(Context.class); // 反射創建 service service = constructor.newInstance(mContext); } catch (InstantiationException ex) { throw new RuntimeException("Failed to create service " + name + ": service could not be instantiated", ex); } catch (IllegalAccessException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (NoSuchMethodException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (InvocationTargetException ex) { throw new RuntimeException("Failed to create service " + name + ": service constructor threw an exception", ex); } startService(service); return service; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } }

創建並啟動一個系統服務。這個系統服務必須是 com.android.server.SystemService 的子類。根據參數傳入的 Class 對象反射創建其實例,再調用重載方法 startService() :

public void startService(@NonNull final SystemService service) { // Register it. mServices.add(service); // Start it. long time = SystemClock.elapsedRealtime(); try { // 回調系統服務的 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"); }

就兩步。第一步,註冊服務,mServices 是一個 ArrayList 對象,用來保存已經創建的系統服務。第二步,回調服務的 onStart() 方法,還是以 Installer 為例:

@Override public void onStart() { if (mIsolated) { mInstalld = null; } else { connect(); } }

這樣一個服務就啟動完成了。這是一種比較普遍的啟動方式,當然還有一些系統服務具有不一樣的啟動方式,這裡就不一一分析了,後面有機會解析具體服務的時候再來分析。

總結

SystemServer 的啟動流程比較耿直,沒有那麼多彎彎繞,下面簡單總結一下:

語言、時區、地區等設置虛擬機內存設置指紋信息,Binder 調用設置Looper.prepareMainLooper() ,創建主線程 Looper初始化 native 服務,加載 libandroid_servers.socreateSystemContext(),初始化系統上下文創建系統服務管理 SystemServiceManagerstartBootstrapServices,啟動系統引導服務startCoreServices,啟動系統核心服務startOtherServices,啟動其他服務Looper.loop(),開啟消息循環

另外,在 startOtherServices 的最後會調用 AMS 的 onSystemReady() 方法啟動桌面 Activity。

預告

還記得 Zygote 進程的 runSelectLoop() 方法嗎?Zygote 在創建完 system_server 進程之後,就開始默默的等待客戶端請求創建應用進程。下一篇,我們將從源碼角度來捋一遍客戶端是如何發送請求,Zygote 是如何處理請求,應用進程是如何創建的,敬請期待!