(1)SystemServer啟動
SystemServer的程序名實際上叫做“system_server”,通常簡稱為SS。
是系統中的服務駐留在其中,常見的比如WindowManagerServer(WmS)、ActivityManagerSystemService(AmS)、 PackageManagerServer(PmS)等,這些系統服務都是以一個線程的方式存在于SystemServer程序中。
//frameworks/base/services/java/com/android/server/SystemServer.java
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
// Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
mRuntimeStartUptime = SystemClock.uptimeMillis();
}
SystemServer是一個Java類,從main函數入口分析,主要調用run方法
//frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
try {
traceBeginAndSlog("InitBeforeStartServices");
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
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);
// 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();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
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);
// Ensure binder calls into the system always run at foreground priority.
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);
Looper.prepareMainLooper();
// Initialize native services.
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
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();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
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);
}
}
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
以上run方法的主要工作如下:
- 調整時間,如果系統時間比1970還要早,調整到1970年
- 設定語言
- 調整虛拟機堆記憶體大小和記憶體使用率
- 初始化Looper為mainLooper
- 裝載庫libandroid_server.so
- 初始化系統Context
- 建立SystemServiceManager負責系統Service啟動
- 啟動各種服務
- 調用Looper.loop(),進入處理消息的循環
這裡簡單介紹幾個功能:
(1)初始化系統Context,可用于後續建立SystemServiceManager等
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);
}
(2)建立SystemServiceManager執行個體
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
可用于後面通過SystemServiceManager.start方法啟動各種服務。
(3)建立和啟動服務有兩種方式
//(1)通過SystemServiceManager.start
mSystemServiceManager.startService(AlarmManagerService.class);
mSystemServiceManager.startService(DisplayManagerService.class);
mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
//(2)通過ServiceManager.addService
ServiceManager.addService("telephony.registry", telephonyRegistry);
ServiceManager.addService(Context.SYSTEM_UPDATE_SERVICE,
new SystemUpdateManagerService(context));
ServiceManager.addService(Context.MEDIA_ROUTER_SERVICE, mediaRouter);
(4)啟動系統各種核心服務
traceBeginAndSlog("StartBatteryService");
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);
traceEnd();
traceBeginAndSlog("StartActivityManager");
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
traceBeginAndSlog("StartPackageManagerService");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
traceEnd();
traceBeginAndSlog("StartDisplayManager");
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
traceEnd();
(2)AMS.systemReady
systemReady是在SystemServer.startOtherServices的最後被調用,主要的動作是标記和等待各個服務啟動完成如等待PMS啟動結束,緊接着啟動SystemUI和啟動Launcher。
//frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
//startSystemUi
traceBeginAndSlog("StartSystemUI");
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
traceEnd();
//startHomeActivity
traceLog.traceBegin("PhaseActivityManagerReady");
startHomeActivityLocked(currentUserId, "systemReady");
...
}
startSystemUi(SystemUI啟動)
SystemUI是在AMS.systemReady時啟動,主要是通過Intent啟動包名為com.android.systemui元件名為SystemUIService的服務,然後通過調用WindowManager.onSystemUiStarted方法調用KeyguardService啟動鎖屏服務。SystemUI啟動成功後表示系統的通知欄和導航欄已經初始化成功,接下來就是啟動Launcher。
static final void startSystemUi(Context context, WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
startHomeActivity(Launcher啟動)
Launcher的啟動是在AMS的最後,通過startHomeActivityLocked來啟動Launcher的Activity并将其置于Activity棧頂,然後通過resumeFocusedStackTopActivityLocked将棧頂的Activity顯示到界面上,launcher的啟動就已經完成了。
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;
}
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
//獲得HomeActivity的Intent
Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
// For ANR debugging to verify if the user activity is the one that actually
// launched.
final String myReason = reason + ":" + userId + ":" + resolvedUserId;
//用于啟動HomeActivity
mActivityStartController.startHomeActivity(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
接下來我們畫一個簡單的UML圖來表示Android開機全過程。
具體後續的開機動畫(bootanimation)如何啟動和退出的,我們将在後面的博文中在進行詳細分析。