天天看點

Android系統啟動流程完整分析(五)

(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();
           
Android系統啟動流程完整分析(五)

(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;
    }
           
Android系統啟動流程完整分析(五)

接下來我們畫一個簡單的UML圖來表示Android開機全過程。

Android系統啟動流程完整分析(五)

具體後續的開機動畫(bootanimation)如何啟動和退出的,我們将在後面的博文中在進行詳細分析。

繼續閱讀