Android SystemServer 啟動流程

一 什么是SystemServer己肮?

簡單來說厂僧,systemServer就是系統(tǒng)用來啟動各種service的入口她肯,安卓系統(tǒng)在啟動的時候,會初始化兩個重要的部分间影,一個是zygote進程注竿,另一個是由zygote進程fork出來的SystemServer進程,SystemServer會啟動我們系統(tǒng)中所需要的一系列service魂贬,下面會做分析巩割。

二 從源碼出發(fā),分析Systemserver

2.1 SystemServer調(diào)用的入口

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

SystemServer的初始化入口在main()方法中付燥,我們進入run()方法中宣谈,可以看到以下代碼:

private void run() {
    try {
        ......
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

       
        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", "");
        }

        // Here we go!
        Slog.i(TAG, "Entered the Android system server!");
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());

        
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        VMRuntime.getRuntime().clearGrowthLimit();
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
        Build.ensureFingerprintProperty();
        Environment.setUserRequired(true);
        BaseBundle.setShouldDefuse(true);
        BinderInternal.disableBackgroundScheduling(true);


        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);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }

    // Start services.
    try {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

以上代碼已經(jīng)去除了部分無用代碼,我們下面來一步一步的對上面的代碼進行切割分析

if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

首先键科,SystemServer會去判斷系統(tǒng)當前的時間闻丑,如果當前時間小于1970年那么,系統(tǒng)就會把當前的時間設置成1970年勋颖。
接下來嗦嗡,

        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", "");
        }

這代代碼主要是初始化一些基本環(huán)境設置,比如說當前的語言饭玲,國家這些酸钦。
接著,

       SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        VMRuntime.getRuntime().clearGrowthLimit();
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
        Build.ensureFingerprintProperty();
        Environment.setUserRequired(true);
        BaseBundle.setShouldDefuse(true);
        BinderInternal.disableBackgroundScheduling(true);


        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();

        // Initialize native services.
        System.loadLibrary("android_servers");

這一部分主要是加載一些虛擬機環(huán)境和一些運行庫咱枉,這些都不是本文所要分析的重點卑硫,接下來還有一個方法:

  // Initialize the system context.
        createSystemContext();

 private void createSystemContext() {  
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}

這個方法表示SystemServer需要獲取當前系統(tǒng)的上下文
接下來,就會初始化系統(tǒng)的system Service Manager

mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);  

systemManagerService的作用是用來管理service的創(chuàng)建蚕断、開始或者SystemService下的其他生命周期事件欢伏。好了,接下來就是重頭戲來了

try {
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
    } catch (Throwable ex) {
        ......
        throw ex;
    } finally {
          ......
    }  

從谷歌給我們的注釋我們給出以上三個方法簡單的解釋
1 startBootstrapServices() 主要是用來開啟一些系統(tǒng)級別的service亿乳,這些service具有高度的復雜的相互依賴關系硝拧,所以我們需要把他們的初始化放在同一個地方
2 startCoreServices() 主要是啟動一些核心的Service径筏,但是這些service跟我們的bootservice沒有相互依賴關系的,是相對獨立的服務
2 startOtherServices() 正如英文所示障陶,這是一些費關鍵非核心的service

Step 1 分析startBootstrapService()方法

private void startBootstrapServices() {
    Installer installer = mSystemServiceManager.startService(Installer.class);

    traceBeginAndSlog("DeviceIdentifiersPolicyService");
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
    traceEnd();

    // Activity manager runs the show.
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    // Power manager needs to be started early because other services need it.
    // Native daemons may be watching for it to be registered so it must be ready
    // to handle incoming binder calls immediately (including being able to verify
    // the permissions for those calls).
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    // Now that the power manager has been started, let the activity manager
    // initialize power management features.
    Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");
    mActivityManagerService.initPowerManagement();
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

    // Manages LEDs and display backlight so we need it to bring up the display.
    mSystemServiceManager.startService(LightsService.class);

    // Display manager is needed to provide display metrics before package manager
    // starts up.
    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);

    // Only run "core" apps if we're encrypting the device.
    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;
    }

    // Start the package manager.
    traceBeginAndSlog("StartPackageManagerService");
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

    // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
    // A/B artifacts after boot, before anything else might touch/need them.
    // Note: this isn't needed during decryption (we don't have /data anyways).
    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 {
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
            }
        }
    }

    traceBeginAndSlog("StartUserManagerService");
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

    // Initialize attribute cache used to cache resources from packages.
    AttributeCache.init(mSystemContext);

    // Set up the Application instance for the system process and get started.
    mActivityManagerService.setSystemProcess();

    // The sensor service needs access to package manager service, app ops
    // service, and permissions service, therefore we start it after them.
    startSensorService();
}  

在這段代碼中滋恬,我們先分析核心的代碼:

    traceBeginAndSlog("StartInstaller");
    Installer installer = mSystemServiceManager.startService(Installer.class);
    traceEnd();

    // In some cases after launching an app we need to access device identifiers,
    // therefore register the device identifier policy before the activity manager.
    traceBeginAndSlog("DeviceIdentifiersPolicyService");
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
    traceEnd();

這段代碼的執(zhí)行,就是為了先啟動installer抱究,這樣android才有機會去創(chuàng)建一些關鍵的路徑(data/user),這些都需要在其他Service啟動前完成恢氯。其次,通過mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);這段代碼鼓寺,android需要注冊當前的設備表示勋拟,以防有一些特殊的時候需要用到。
我們進入install類的onStart()方法一看

@Override
public void onStart() {
    if (mIsolated) {
        mInstalld = null;
    } else {
        connect();
    }
}  
private void connect() {
    IBinder binder = ServiceManager.getService("installd");
    if (binder != null) {
        try {
            binder.linkToDeath(new DeathRecipient() {
                @Override
                public void binderDied() {
                    Slog.w(TAG, "installd died; reconnecting");
                    connect();
                }
            }, 0);
        } catch (RemoteException e) {
            binder = null;
        }
    }

    if (binder != null) {
        mInstalld = IInstalld.Stub.asInterface(binder);
        try {
            invalidateMounts();
        } catch (InstallerException ignored) {
        }
    } else {
        Slog.w(TAG, "installd not found; trying again");
        BackgroundThread.getHandler().postDelayed(() -> {
            connect();
        }, DateUtils.SECOND_IN_MILLIS);
    }
}

我們可以看到妈候,其實這就是一個遞歸敢靡。install通過調(diào)用connect,去判斷installer是否被初始化苦银。只有installer被初始化了啸胧,才會繼續(xù)往下掉用,初始化其他的服務幔虏。
接下來纺念,啟動ActivityManagerService。我們通過代碼分析:

    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

我們開啟ams傳入的是 ActivityManagerService.Lifecycle.class所计,同時把installer傳入給ams柠辞。我們進入AMS查看代碼团秽,可以看到

final void finishBooting() {
    ...
    for (String abi : Build.SUPPORTED_ABIS) {
        zygoteProcess.establishZygoteConnectionForAbi(abi);
        final String instructionSet = VMRuntime.getInstructionSet(abi);
        if (!completedIsas.contains(instructionSet)) {
            try {
                mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
            } catch (InstallerException e) {
                Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
                        e.getMessage() +")");
            }
            completedIsas.add(instructionSet);
        }
    }
  ...
 }

所以finishBooting是ams和zygote進行通訊的入口习勤。
startBootstrapServices()方法中夷都,還啟動了很多其他的services囤官,包括PowerManagerService、RecoverySystemService刑顺、LightsService蹲堂、DisplayManagerService等等柒竞,這里就不重復做出分析了鲫骗。

Step 2 分析startCoreServices()方法

private void startCoreServices() {
    // Records errors and logs, for example wtf()
    traceBeginAndSlog("StartDropBoxManager");
    mSystemServiceManager.startService(DropBoxManagerService.class);
    traceEnd();

    traceBeginAndSlog("StartBatteryService");
    // Tracks the battery level.  Requires LightService.
    mSystemServiceManager.startService(BatteryService.class);
    traceEnd();

    // Tracks application usage stats.
    traceBeginAndSlog("StartUsageService");
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));
    traceEnd();

    // Tracks whether the updatable WebView is in a ready state and watches for update installs.
    traceBeginAndSlog("StartWebViewUpdateService");
    mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    traceEnd();
}  

這個方法主要啟動一些跟bootstrap進程無關的service渡蜻,這里比較好玩的是茸苇,android會在這里去檢測WebView是處于就緒狀態(tài)和手動更新安裝淘衙。
Step 3 分析startOtherServices()方法
這個方法過長,就不貼上源碼的具垫,這個方法主要是為了整理或者重構一些雜七雜八的包,不太重要起宽,不做分析。

總結

至此屏箍,systemServer啟動流程分析完畢卸奉,可能篇幅太長榄棵,大家需要自己好好整理疹鳄,沒事多復習。

(1)SystemServer進程是android中一個很重要的進程由Zygote進程啟動腺怯;

(2)SystemServer進程主要用于啟動系統(tǒng)中的服務;

(3)SystemServer進程啟動服務的啟動函數(shù)為main函數(shù)晾虑;

(4)SystemServer在執(zhí)行過程中首先會初始化一些系統(tǒng)變量惑芭,加載類庫,創(chuàng)建Context對象幻锁,創(chuàng)建SystemServiceManager對象等之后才開始啟動系統(tǒng)服務;

(5)SystemServer進程將系統(tǒng)服務分為三類:boot服務富拗,core服務和other服務,并逐步啟動

(6)SertemServer進程在嘗試啟動服務之前會首先嘗試與Zygote建立socket通訊,只有通訊成功之后才會開始嘗試啟動服務;

(7)創(chuàng)建的系統(tǒng)服務過程中主要通過SystemServiceManager對象來管理,通過調(diào)用服務對象的構造方法和onStart方法初始化服務的相關變量;

(8)服務對象都有自己的異步消息對象河泳,并運行在單獨的線程中;
(備注)以上8點的總結,參考的是http://blog.csdn.net/qq_23547831/article/details/51105171 在此感謝作者

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末备禀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纽乱,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件话原,死亡現(xiàn)場離奇詭異,居然都是意外死亡诲锹,警方通過查閱死者的電腦和手機繁仁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來归园,“玉大人黄虱,你說我怎么就攤上這事∮褂眨” “怎么了捻浦?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桥爽。 經(jīng)常有香客問我朱灿,道長,這世上最難降的妖魔是什么钠四? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任盗扒,我火速辦了婚禮,結果婚禮上缀去,老公的妹妹穿的比我還像新娘侣灶。我一直安慰自己,他們只是感情好缕碎,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布褥影。 她就那樣靜靜地躺著,像睡著了一般咏雌。 火紅的嫁衣襯著肌膚如雪凡怎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天处嫌,我揣著相機與錄音栅贴,去河邊找鬼斟湃。 笑死熏迹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的凝赛。 我是一名探鬼主播注暗,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼坛缕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捆昏?” 一聲冷哼從身側(cè)響起赚楚,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎骗卜,沒想到半個月后宠页,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡寇仓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年举户,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遍烦。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡俭嘁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出服猪,到底是詐尸還是另有隱情供填,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布罢猪,位于F島的核電站近她,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏膳帕。R本人自食惡果不足惜泄私,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望备闲。 院中可真熱鬧晌端,春花似錦、人聲如沸恬砂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽泻骤。三九已至漆羔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狱掂,已是汗流浹背演痒。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留趋惨,地道東北人鸟顺。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讯嫂。 傳聞我的和親對象是個殘疾皇子蹦锋,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容