Android系統(tǒng)啟動之SystemServer

image.png

目錄

第一篇:Android系統(tǒng)啟動之bootloader
第二篇:Android系統(tǒng)啟動之Init流程(上)
第三篇:Android系統(tǒng)啟動之Init流程(下)
第四篇:Android系統(tǒng)啟動之init.rc文件解析過程
第五篇:Android系統(tǒng)啟動之zyogte進(jìn)程
第六篇:Android系統(tǒng)啟動之zyogte進(jìn)程java(上)
第七篇:Android系統(tǒng)啟動之zyogte進(jìn)程java(下)
第八篇:Android系統(tǒng)啟動之SystemServer

SystemServer

首先看下什么是SystemServer?

SystemServer的進(jìn)程名實(shí)際上叫做“system_server”,通常簡稱為SS屹堰。
是系統(tǒng)中的服務(wù)駐留在其中,常見的比如WindowManagerServer(Wms)、ActivityManagerSystemService(AmS)忌怎、 PackageManagerServer(PmS)等傅是,這些系統(tǒng)服務(wù)都是以一個線程的方式存在于SystemServer進(jìn)程中岂丘。

SystemServer啟動

SystemServer是由Zygote啟動的.
源碼路徑frameworks/base/services/java/com/android/server/SystemServer.java

     /**
       * The main entry point from zygote.
       */
      public static void main(String[] args) {
          new SystemServer().run();
      }

這樣SystemServer便啟動起來了.

run函數(shù)

我們來看下run的實(shí)現(xiàn)

    private void run() {
        try {
            traceBeginAndSlog("InitBeforeStartServices");
            // If a device's clock is before 1970 (before 0), a lot of
            // APIs crash dealing with negative numbers, notably
            // java.io.File#setLastModified, so instead we fake it and
            // hope that time from cell towers or NTP fixes it shortly.
//---------------------------------------------------------------
//-----------------------1.設(shè)定時(shí)間-------------------------------
//---------------------------------------------------------------
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }

            //
            // Default the timezone property to GMT if not set.
            //
            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 the system has "persist.sys.language" and friends set, replace them with
            // "persist.sys.locale". Note that the default locale at this point is calculated
            // using the "-Duser.locale" command line flag. That flag is usually populated by
            // AndroidRuntime using the same set of system properties, but only the system_server
            // and system apps are allowed to set them.
            //
            // NOTE: Most changes made here will need an equivalent change to
            // core/jni/AndroidRuntime.cpp
//---------------------------------------------------------------
//-----------------------2.設(shè)定語言-------------------------------
//---------------------------------------------------------------
            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);
            }

            // In case the runtime switched since last boot (such as when
            // the old runtime was removed in an OTA), set the system
            // property so that it is in sync. We can | xq oqi't do this in
            // libnativehelper's JniInvocation::Init code where we already
            // had to fallback to a different runtime because it is
            // running as root and we need to be the system user to set
            // the property. http://b/11463182
//---------------------------------------------------------------
//-----------------------3.虛擬機(jī)庫文件路徑  ---------------------
//---------------------------------------------------------------
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

            // Enable the sampling profiler.
            //開啟性能分析
            if (SamplingProfilerIntegration.isEnabled()) {
                SamplingProfilerIntegration.start();
                mProfilerSnapshotTimer = new Timer();
                mProfilerSnapshotTimer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            SamplingProfilerIntegration.writeSnapshot("system_server", null);
                        }
                    }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
            }

            // Mmmmmm... more memory!
//---------------------------------------------------------------
//-----------------------4.清除內(nèi)存使用上線  ---------------------
//---------------------------------------------------------------
            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.
            //設(shè)定內(nèi)存使用率
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

            // Some devices rely on runtime fingerprint generation, so make sure
            // we've defined it before booting further.
//---------------------------------------------------------------
//-----------------------5.設(shè)定指紋使用  ------------------------
//---------------------------------------------------------------
            Build.ensureFingerprintProperty();

            // Within the system server, it is an error to access Environment paths without
            // explicitly specifying a user.
//---------------------------------------------------------------
//-----------------------6.設(shè)定環(huán)境變量訪問用戶條件  --------------
//---------------------------------------------------------------
            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.
//---------------------------------------------------------------
//-----------------------7.設(shè)定binder服務(wù)永遠(yuǎn)運(yùn)行在前臺  ----------
//---------------------------------------------------------------
            BinderInternal.disableBackgroundScheduling(true);

            // Increase the number of binder threads in system_server
//---------------------------------------------------------------
//-----------------------8.設(shè)定線程池最大線程數(shù)-------------------
//---------------------------------------------------------------
            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.
//---------------------------------------------------------------
//-----------------------9.啟動各種服務(wù)  ------------------------
//---------------------------------------------------------------
        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.
//---------------------------------------------------------------
//-----------------------10.debug模式開啟log  ------------------
//---------------------------------------------------------------
        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.
//---------------------------------------------------------------
//-----------------------11.服務(wù)開啟循環(huán)  ------------------
//---------------------------------------------------------------
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

代碼中大致分為11個步驟:
1.設(shè)定時(shí)間
2.設(shè)定語言
3.虛擬機(jī)庫文件路徑
4.清除內(nèi)存使用上線
5.設(shè)定指紋使用
6.設(shè)定環(huán)境變量訪問用戶條件
7.設(shè)定binder服務(wù)永遠(yuǎn)運(yùn)行在前臺
8.設(shè)定線程池最大線程數(shù)
9.啟動各種服務(wù)
10.debug模式開啟log
11.服務(wù)開啟循環(huán)

啟動系統(tǒng)上下文

            // Initialize the system context.
            createSystemContext();

函數(shù)實(shí)現(xiàn)為base/services/java/com/android/server/SystemServer.java:475:

     private void createSystemContext() {
//---------------------------------------------------------------
//-----------------------1.獲取ActivityThread對象  ------------------
//---------------------------------------------------------------
         ActivityThread activityThread = ActivityThread.systemMain();
//---------------------------------------------------------------
//-----------------------2.獲取系統(tǒng)上下文  ------------------
//---------------------------------------------------------------
         mSystemContext = activityThread.getSystemContext();
 //---------------------------------------------------------------
//-----------------------3.設(shè)定系統(tǒng)主題  ------------------
//---------------------------------------------------------------
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
 
         final Context systemUiContext = activityThread.getSystemUiContext();
         systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
     }

代碼中大致分為3個步驟:
1.獲取ActivityThread對象
2.獲取系統(tǒng)上下文
3.設(shè)定系統(tǒng)主題

創(chuàng)建SystemServiceManage

    // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
     

構(gòu)造函數(shù)實(shí)現(xiàn)為base/services/core/java/com/android/server/SystemServiceManager.java

      SystemServiceManager(Context context) {
          mContext = context;
      }

幾乎什么也沒做.
addService函數(shù)實(shí)現(xiàn)frameworks/base/core/java/com/android/server/LocalServices.java

      /**
      * Adds a service instance of the specified interface to the global registry of loca    l services.
      */
      public static <T> void addService(Class<T> type, T service) {
          synchronized (sLocalServiceObjects) {
              if (sLocalServiceObjects.containsKey(type)) {
                  throw new IllegalStateException("Overriding service registration");
             }
            sLocalServiceObjects.put(type, service);
         }
     }

參考

Android 內(nèi)核初識(6)SystemServer進(jìn)程
Android系統(tǒng)啟動——6 SystemServer啟動

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末储矩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子风纠,更是在濱河造成了極大的恐慌蚯斯,老刑警劉巖薄风,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拍嵌,居然都是意外死亡遭赂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門横辆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撇他,“玉大人,你說我怎么就攤上這事狈蚤±Ъ纾” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵脆侮,是天一觀的道長锌畸。 經(jīng)常有香客問我,道長靖避,這世上最難降的妖魔是什么潭枣? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任比默,我火速辦了婚禮,結(jié)果婚禮上盆犁,老公的妹妹穿的比我還像新娘命咐。我一直安慰自己,他們只是感情好谐岁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布醋奠。 她就那樣靜靜地躺著,像睡著了一般伊佃。 火紅的嫁衣襯著肌膚如雪窜司。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天锭魔,我揣著相機(jī)與錄音例证,去河邊找鬼。 笑死迷捧,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胀葱。 我是一名探鬼主播漠秋,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抵屿!你這毒婦竟也來了庆锦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤轧葛,失蹤者是張志新(化名)和其女友劉穎搂抒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尿扯,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡求晶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衷笋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芳杏。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖辟宗,靈堂內(nèi)的尸體忽然破棺而出爵赵,到底是詐尸還是另有隱情,我是刑警寧澤泊脐,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布空幻,位于F島的核電站,受9級特大地震影響容客,放射性物質(zhì)發(fā)生泄漏秕铛。R本人自食惡果不足惜约郁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望如捅。 院中可真熱鬧棍现,春花似錦、人聲如沸镜遣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽悲关。三九已至谎僻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寓辱,已是汗流浹背艘绍。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秫筏,地道東北人诱鞠。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像这敬,于是被迫代替她去往敵國和親航夺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

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

  • 以前看到一些精美的崔涂、觸動內(nèi)心等等的美文阳掐,總羨慕那些文人才子,寫出那么觸動人心的文章冷蚂,總幻想如果自己也能寫出一篇像樣...
    葑芯瑣愛閱讀 303評論 0 1
  • 目的: 任何模式的出現(xiàn)缭保,都是為了解決一些特定的場景的耦合問題,以達(dá)到對修改封閉蝙茶,對擴(kuò)展開放的效果艺骂。命令模式也不例外...
    時(shí)待吾閱讀 313評論 0 0