溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

什么是SystemServer進程

發(fā)布時間:2021-10-20 16:02:36 來源:億速云 閱讀:126 作者:iii 欄目:移動開發(fā)

這篇文章主要講解了“什么是SystemServer進程”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“什么是SystemServer進程”吧!

誕生

之前在Android系統(tǒng)的啟動過程中???說到,SystemServer進程是由Zygote進程fork而來。

fork()函數(shù)通過系統(tǒng)調(diào)用創(chuàng)建一個與原來進程幾乎完全相同的進程,可以理解為COPY了一個進程出來,而這個新進程就是它的子進程。

而關于SystemServer的誕生,還要從ZygoteInit的forkSystemServer方法說起...(只保留主要代碼)

private static Runnable forkSystemServer(String abiList, String socketName,            ZygoteServer zygoteServer) {        //...          // 1        int pid;        pid = Zygote.forkSystemServer(                    parsedArgs.uid, parsedArgs.gid,                    parsedArgs.gids,                    parsedArgs.runtimeFlags,                    null,                    parsedArgs.permittedCapabilities,                    parsedArgs.effectiveCapabilities);         /* For child process */        if (pid == 0) {            //2            zygoteServer.closeServerSocket();            //3            return handleSystemServerProcess(parsedArgs);        }         return true;    }     /**     * Finish remaining work for the newly forked system server process.     */    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {             //...              /*             * Pass the remaining arguments to SystemServer.             */            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);    }      public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {        //...      //4         RuntimeInit.commonInit();        //5        ZygoteInit.nativeZygoteInit();        //6        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);    }

startSystemServer方法中:

  • 1、調(diào)用forkSystemServer方法創(chuàng)建了子進程——SystemServer進程。

  • 2、fork之后,這里判斷了fork的返回值pid是否等于0,如果等于0,就代表fork成功,就處在SystemServer進程中了。然后關閉了從Zygote進程fork帶來的Socket對象。

  • 3、然后調(diào)用了handleSystemServerProcess方法,并最終走到zygoteInit,做了一些新進程的初始化工作。

zygoteInit方法中:

  • 4、commonInit方法就是做了一些進程通用的初始化工作,比如設置時區(qū),重置log配置。

  • 5、nativeZygoteInit方法通過JNI會走到native層,主要的工作就是創(chuàng)建了新的Binder線程池,這樣SystemServer才能和各大app進程進行通信。

  • 6、applicationInit方法,最終會走到findStaticMain方法中,通過反射調(diào)用SystemServer類的main方法,簡單貼下代碼:

protected static Runnable findStaticMain(String className, String[] argv,            ClassLoader classLoader) {        Class<?> cl;         try {            cl = Class.forName(className, true, classLoader);        }         //...         Method m;        try {            m = cl.getMethod("main", new Class[] { String[].class });        }         //...              return new MethodAndArgsCaller(m, argv);    }

工作

SystemServer進程創(chuàng)建出來了,并且做了一些初始化工作,接下來就來到了main方法了,顧名思義,肯定要開始正經(jīng)主要的工作了。

public static void main(String[] args) {         new SystemServer().run();     }       private void run() {         try {             //...              // 1             android.os.Process.setThreadPriority(                 android.os.Process.THREAD_PRIORITY_FOREGROUND);             android.os.Process.setCanSelfBackground(false);              Looper.prepareMainLooper();             Looper.getMainLooper().setSlowLogThresholdMs(                     SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);              // 2             System.loadLibrary("android_servers");              // 3             performPendingShutdown();              // 4             createSystemContext();              // 5             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();          }          //...          // Start services.         try {             //6             startBootstrapServices();             //7             startCoreServices();             //8             startOtherServices();             SystemServerInitThreadPool.shutdown();         }           //...          // Loop forever.         Looper.loop();         throw new RuntimeException("Main thread loop unexpectedly exited");     }
  • 1、準備主線程,Looper。

  • 2、加載動態(tài)庫。

  • 3、檢測上次關機過程是否失敗。

  • 4、初始化系統(tǒng)上下文。

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

在這個方法中,創(chuàng)建了ActivityThread類,獲取了上下文,并設置了一些系統(tǒng)主題。

  • 5、創(chuàng)建SystemServiceManager,用于后續(xù)的系統(tǒng)服務管理創(chuàng)建等工作。

run方法最后的工作就是啟動三個服務類型的服務,也是我們重點關注的,分別是引導服務,核心服務,其他服務。

這些服務一共有100多個,關系著Android整個應用生態(tài),下面我們具體說下。

  • 6、啟動引導服務

private void startBootstrapServices() {          //安裝APK服務         traceBeginAndSlog("StartInstaller");         Installer installer = mSystemServiceManager.startService(Installer.class);         traceEnd();          //AMS,負責四大組件的啟動調(diào)度等工作         mActivityManagerService = mSystemServiceManager.startService(                 ActivityManagerService.Lifecycle.class).getService();         mActivityManagerService.setSystemServiceManager(mSystemServiceManager);         mActivityManagerService.setInstaller(installer);         traceEnd();           // 管理和顯示背光LED等服務         traceBeginAndSlog("StartLightsService");         mSystemServiceManager.startService(LightsService.class);         traceEnd();          //PMS,負責APK安裝,解析卸載等工作         traceBeginAndSlog("StartPackageManagerService");         mPackageManagerService = PackageManagerService.main(mSystemContext, installer,                 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);         mFirstBoot = mPackageManagerService.isFirstBoot();         mPackageManager = mSystemContext.getPackageManager();         traceEnd();          //...      }

引導服務中,有幾個我們畢竟熟悉的,比如AMS、PMS。

  • 7、啟動核心服務

private void startCoreServices() {         traceBeginAndSlog("StartBatteryService");         // 管理電池相關服務         mSystemServiceManager.startService(BatteryService.class);         traceEnd();          // 收集用戶使用時長服務         traceBeginAndSlog("StartUsageService");         mSystemServiceManager.startService(UsageStatsService.class);         mActivityManagerService.setUsageStatsManager(                 LocalServices.getService(UsageStatsManagerInternal.class));         traceEnd();          // Webview更新服務         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {             traceBeginAndSlog("StartWebViewUpdateService");             mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);             traceEnd();         }          //...     }
  • 8、啟動其他服務

private void startOtherServices() {    //...               //電話管理服務             traceBeginAndSlog("StartTelephonyRegistry");             telephonyRegistry = new TelephonyRegistry(context);             ServiceManager.addService("telephony.registry", telephonyRegistry);             traceEnd();                   //WMS,窗口管理服務,也是打交道比較多的             traceBeginAndSlog("StartWindowManagerService");             ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);             mSensorServiceStart = null;             wm = WindowManagerService.main(context, inputManager,                     mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,                     !mFirstBoot, mOnlyCore, new PhoneWindowManager());             ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);             ServiceManager.addService(Context.INPUT_SERVICE, inputManager,                     /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);             traceEnd();               //輸入事件管理服務             traceBeginAndSlog("StartInputManager");             inputManager.setWindowManagerCallbacks(wm.getInputMonitor());             inputManager.start();             traceEnd();                   //...      }

啟動了這么多服務,我們再看一下服務都是怎么具體啟動的:

public <T extends SystemService> T startService(Class<T> serviceClass) {        try {            final String name = serviceClass.getName();             // Create the service.            final T service;            try {                Constructor<T> constructor = serviceClass.getConstructor(Context.class);                service = constructor.newInstance(mContext);            } //...            startService(service);            return service;        } finally {            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);        }    }     // 所有系統(tǒng)服務的集合    private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();         public void startService(@NonNull final SystemService service) {        // Register it.        mServices.add(service);        // Start it.        long time = SystemClock.elapsedRealtime();        try {            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");    }

可以看到,首先通過反射創(chuàng)建了對應的Service類,然后把對應的Service加入到mServices集合中,完成注冊。然后調(diào)用onStart方法啟動對應的Service,完成初始化工作。

到這里,SystemServer的啟動工作就完成了,再來回顧下,這個過程,到底干了些啥?

  • 首先,Zygote fork了SystemServer這個子進程,然后關閉了原有的socket,創(chuàng)建了新的Binder線程池。

  • 其次,做了一些初始化工作,創(chuàng)建了Context對象,創(chuàng)建了SystemServiceManager類,用于管理所有的系統(tǒng)服務。

  • 最后,啟動了三類系統(tǒng)服務,分別是引導服務,核心服務和其他服務。

體系知識延伸

Socket和Binder

我們注意到,在SystemServer被fork出來之后,做了一個操作就是關閉了Sokcet,啟動了Binder線程池用于進程間通信。問題來了,為啥Zygote進程是用Socket通信,而SystemServer進程是用Binder進行通信呢?

其實這是兩個問題,第一個問題是問為什么Android獲取系統(tǒng)服務是用的Binder進程通信呢?

這就涉及到Binder的知識點了,Binder之所以被設計出來,就是因為它有區(qū)別于其他IPC方式的兩大優(yōu)點:

  • 性能高,效率高:傳統(tǒng)的IPC(套接字、管道、消息隊列)需要拷貝兩次內(nèi)存、Binder只需要拷貝一次內(nèi)存、共享內(nèi)存不需要拷貝內(nèi)存。

  • 安全性好:接收方可以從數(shù)據(jù)包中獲取發(fā)送發(fā)的進程Id和用戶Id,方便驗證發(fā)送方的身份,其他IPC想要實驗只能夠主動存入,但是這有可能在發(fā)送的過程中被修改。

第二個問題就是,為什么Zygote進程不用Binder而用Socket通信呢?這也是wanAndroid中的一個問題:

每日一問 |  Activity啟動流程中,大部分都是用Binder通訊,為啥跟Zygote通信的時候要用socket呢?(https://www.wanandroid.com/wenda/show/10482)

評論區(qū)主要有以下觀點:

  • ServiceManager不能保證在zygote起來的時候已經(jīng)初始化好,所以無法使用Binder。

  • Socket 的所有者是 root,只有系統(tǒng)權(quán)限用戶才能讀寫,多了安全保障。

  • Binder工作依賴于多線程,但是fork的時候是不允許存在多線程的,多線程情況下進程fork容易造成死鎖,所以就不用Binder了。

Binder線程池

Binder線程池到底是什么?之前有讀者也問過類似的問題。

Binder線程池位于服務端,它的主要作用就是將每個業(yè)務模塊的Binder請求統(tǒng)一轉(zhuǎn)發(fā)到遠程Servie中去執(zhí)行,從而避免了重復創(chuàng)建Service的過程。也就是服務端只有一個,但是可以處理多個不同客戶端的Binder請求。

AMS,PMS,WMS

在SystemServer進程啟動的過程中,也啟動了很多系統(tǒng)服務,其中就包括和應用交互比較多的三個服務:

  • AMS,ActivityManagerService,負責四大組件的啟動,切換,調(diào)度工作。

  • PMS,PackageManagerService,負責APK的安裝,解析,卸載工作。

  • WMS,WindowManagerService,負責窗口啟動,添加,刪除等工作。

感謝各位的閱讀,以上就是“什么是SystemServer進程”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對什么是SystemServer進程這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI