本文基於 Android 9.0 , 代碼倉庫地址 : android_9.0.0_r45java
文中源碼連接:android
首先來回顧一下上篇文章 Java 世界的盤古和女媧 —— Zygote ,主要介紹了 Android 世界中的第一個 Java 進程 Zygote
,它的主要工做流程以下:安全
registerServerSocketFromEnv()
, 註冊服務端 socket,用於和客戶端進程通訊preload()
,預加載一系列資源,提升應用啓動速度forkSystemServer()
,建立 system_server
進程runSelectLoop()
等待響應客戶端請求,建立應用進程本篇文章的主角 system_server
進程是 Zygote
進程 fork 出的第一個進程,它負責管理和啓動整個 Framework 層。微信
再來看看 Gityuan 的這張圖片,找一下 System Server
的位置,它承載了各種系統服務的建立和啓動。關於 system_server
進程的建立流程,上篇文章中已經作了詳細介紹,這裏再簡單看一下流程圖:app
最終會調用到 SystemServer.main()
方法。下面就以此爲起點,來具體分析 SystemServer 都作了些什麼。socket
public static void main(String[] args) {
new SystemServer().run();
}
複製代碼
接着看 run()
方法。ide
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。關於 Handler 消息機制,能夠閱讀個人另外一篇文章 深刻理解 Handler 消息機制 。最後會調用 Looper.loop()
開啓消息循環,開始處理消息。
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. 啓動其餘服務
複製代碼
逐一進行分析。
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.PHASE_WAIT_FOR_DEFAULT_DISPLAY (100)
PackageManagerService
UserManagerService
OverlayManagerService
SensorService
一共啓動了十二個核心服務。注意中間的 SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY
,它並非表明什麼系統服務,而是一個 int 值 100
,相似的 int 值還有一些,定義在 SystemService
類中,它的做用是給服務啓動過程劃分階段,每一個階段都有特定的含義,能夠作不一樣的事情。這裏先混個臉熟,等介紹完全部的服務,再回過頭來總結一下有哪些階段。
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()
源碼有一千多行,就像一個雜貨鋪,啓動了一系列的服務。下面儘可能精簡一下代碼:
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,這樣桌面應用就啓動了。
至此,system_server
進程的主要工做就算完成了,進入 Looper.loop() 狀態,等待其餘線程經過 Handler 發送消息到主線程並處理。
回過頭再來看看前面提到的啓動階段分類,定義在 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 的源碼,它最重要的工做就是建立和啓動各類系統服務。那麼服務通常是如何建立的呢?下面以 startBootstrapServices()
中建立的第一個服務 Installer
爲例來看一下:
Installer installer = mSystemServiceManager.startService(Installer.class);
複製代碼
進入 SystemServiceManager
的 startService()
方法:
public <T extends SystemService> T startService(Class<T> 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<T> 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<SystemService>
對象,用來保存已經建立的系統服務。第二步,回調服務的 onStart()
方法,仍是以 Installer
爲例:
@Override
public void onStart() {
if (mIsolated) {
mInstalld = null;
} else {
connect();
}
}
複製代碼
這樣一個服務就啓動完成了。這是一種比較廣泛的啓動方式,固然還有一些系統服務具備不同的啓動方式,這裏就不一一分析了,後面有機會解析具體服務的時候再來分析。
SystemServer
的啓動流程比較耿直,沒有那麼多彎彎繞,下面簡單總結一下:
Looper.prepareMainLooper()
,建立主線程 Looperlibandroid_servers.so
createSystemContext()
,初始化系統上下文SystemServiceManager
startBootstrapServices
,啓動系統引導服務startCoreServices
,啓動系統核心服務startOtherServices
,啓動其餘服務Looper.loop()
,開啓消息循環另外,在 startOtherServices
的最後會調用 AMS 的 onSystemReady()
方法啓動桌面 Activity。
還記得 Zygote
進程的 runSelectLoop()
方法嗎?Zygote 在建立完 system_server
進程以後,就開始默默的等待客戶端請求建立應用進程。下一篇,咱們將從源碼角度來捋一遍客戶端是如何發送請求,Zygote 是如何處理請求,應用進程是如何建立的,敬請期待!
文章首發微信公衆號:
秉心說
, 專一 Java 、 Android 原創知識分享,LeetCode 題解。更多最新原創文章,掃碼關注我吧!