您好,登錄后才能下訂單哦!
這篇文章主要講解了“什么是SystemServer進程”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“什么是SystemServer進程”吧!
誕生
之前在Android系統的啟動過程中???說到,SystemServer進程是由Zygote進程fork而來。
fork()函數通過系統調用創建一個與原來進程幾乎完全相同的進程,可以理解為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、調用forkSystemServer方法創建了子進程——SystemServer進程。
2、fork之后,這里判斷了fork的返回值pid是否等于0,如果等于0,就代表fork成功,就處在SystemServer進程中了。然后關閉了從Zygote進程fork帶來的Socket對象。
3、然后調用了handleSystemServerProcess方法,并最終走到zygoteInit,做了一些新進程的初始化工作。
zygoteInit方法中:
4、commonInit方法就是做了一些進程通用的初始化工作,比如設置時區,重置log配置。
5、nativeZygoteInit方法通過JNI會走到native層,主要的工作就是創建了新的Binder線程池,這樣SystemServer才能和各大app進程進行通信。
6、applicationInit方法,最終會走到findStaticMain方法中,通過反射調用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進程創建出來了,并且做了一些初始化工作,接下來就來到了main方法了,顧名思義,肯定要開始正經主要的工作了。
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、加載動態庫。
3、檢測上次關機過程是否失敗。
4、初始化系統上下文。
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); }
在這個方法中,創建了ActivityThread類,獲取了上下文,并設置了一些系統主題。
5、創建SystemServiceManager,用于后續的系統服務管理創建等工作。
run方法最后的工作就是啟動三個服務類型的服務,也是我們重點關注的,分別是引導服務,核心服務,其他服務。
這些服務一共有100多個,關系著Android整個應用生態,下面我們具體說下。
6、啟動引導服務
private void startBootstrapServices() { //安裝APK服務 traceBeginAndSlog("StartInstaller"); Installer installer = mSystemServiceManager.startService(Installer.class); traceEnd(); //AMS,負責四大組件的啟動調度等工作 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); } } // 所有系統服務的集合 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"); }
可以看到,首先通過反射創建了對應的Service類,然后把對應的Service加入到mServices集合中,完成注冊。然后調用onStart方法啟動對應的Service,完成初始化工作。
到這里,SystemServer的啟動工作就完成了,再來回顧下,這個過程,到底干了些啥?
首先,Zygote fork了SystemServer這個子進程,然后關閉了原有的socket,創建了新的Binder線程池。
其次,做了一些初始化工作,創建了Context對象,創建了SystemServiceManager類,用于管理所有的系統服務。
最后,啟動了三類系統服務,分別是引導服務,核心服務和其他服務。
體系知識延伸
Socket和Binder
我們注意到,在SystemServer被fork出來之后,做了一個操作就是關閉了Sokcet,啟動了Binder線程池用于進程間通信。問題來了,為啥Zygote進程是用Socket通信,而SystemServer進程是用Binder進行通信呢?
其實這是兩個問題,第一個問題是問為什么Android獲取系統服務是用的Binder進程通信呢?
這就涉及到Binder的知識點了,Binder之所以被設計出來,就是因為它有區別于其他IPC方式的兩大優點:
性能高,效率高:傳統的IPC(套接字、管道、消息隊列)需要拷貝兩次內存、Binder只需要拷貝一次內存、共享內存不需要拷貝內存。
安全性好:接收方可以從數據包中獲取發送發的進程Id和用戶Id,方便驗證發送方的身份,其他IPC想要實驗只能夠主動存入,但是這有可能在發送的過程中被修改。
第二個問題就是,為什么Zygote進程不用Binder而用Socket通信呢?這也是wanAndroid中的一個問題:
每日一問 | Activity啟動流程中,大部分都是用Binder通訊,為啥跟Zygote通信的時候要用socket呢?(https://www.wanandroid.com/wenda/show/10482)
評論區主要有以下觀點:
ServiceManager不能保證在zygote起來的時候已經初始化好,所以無法使用Binder。
Socket 的所有者是 root,只有系統權限用戶才能讀寫,多了安全保障。
Binder工作依賴于多線程,但是fork的時候是不允許存在多線程的,多線程情況下進程fork容易造成死鎖,所以就不用Binder了。
Binder線程池
Binder線程池到底是什么?之前有讀者也問過類似的問題。
Binder線程池位于服務端,它的主要作用就是將每個業務模塊的Binder請求統一轉發到遠程Servie中去執行,從而避免了重復創建Service的過程。也就是服務端只有一個,但是可以處理多個不同客戶端的Binder請求。
AMS,PMS,WMS
在SystemServer進程啟動的過程中,也啟動了很多系統服務,其中就包括和應用交互比較多的三個服務:
AMS,ActivityManagerService,負責四大組件的啟動,切換,調度工作。
PMS,PackageManagerService,負責APK的安裝,解析,卸載工作。
WMS,WindowManagerService,負責窗口啟動,添加,刪除等工作。
感謝各位的閱讀,以上就是“什么是SystemServer進程”的內容了,經過本文的學習后,相信大家對什么是SystemServer進程這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。