当前位置: 首页 > 科技观察

系统中的大管家——SystemServer进程

时间:2023-03-18 02:53:42 科技观察

本文转载自微信公众号《代码积木》,可通过以下二维码关注。转载本文请联系代码上的积木公众号。前言的第一部分提到了Android系统的启动过程。Zygote进程fork的第一个进程是SystemServer进程。这个进程负责启动和管理JavaFramework层,也就是它提供了很多框架层的服务,比如大家熟知的AMS、PMS、WMS,还有DisplayManagerService、CameraService等,也就是说,它掌握着Android系统的命脉,是Android系统中的大管家。一起来看看吧~(本文源码基于Android9.0)在Android系统诞生之前,据说SystemServer进程是从Zygote进程fork出来的。fork()函数通过系统调用创建了一个和原进程几乎一模一样的进程,可以理解为COPY一个进程,这个新进程就是它的子进程。而关于SystemServer的诞生,还要从ZygoteInit的forkSystemServer方法说起...(只保留主要代码)privatestaticRunnableforkSystemServer(StringabiList,StringsocketName,ZygoteServerzygoteServer){//...//1intpid;pid=Zygote.forkSystemServer.parsedArgSystemServer(parsedArgSystemServer)uid,parsedArgs.gid,parsedArgs.gids,parsedArgs.runtimeFlags,null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);/*Forchildprocess*/if(pid==0){//2zygoteServer.closeServerSocket();//3returnhandleSystemServerProcess(parsedArgs);}returntrue;}/***完成新派生系统服务器进程的剩余工作。*/privatestaticRunnablehandleSystemServerProcess(ZygoteConnection.ArgumentsparsedArgs){//.../**将剩余参数传递给SystemServer。*/ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,parsedArgs.remaining});publicstaticfinalRunnablezygoteInit(inttargetSdkVersion,String[]argv,ClassLoaderclassLoader){//...//4RuntimeInit.commonInit();//5ZygoteInit.nativeZygoteInit();//6returnRuntimeInit.applicationInit(targetSdkVersion,argv,classLoader);}startSystemServer方法:1、调用forkSystemServer方法创建一个子进程——SystemServer进程2、fork之后,这里判断fork的返回值pid是否等于0,如果是等于0,表示分叉成功。它在SystemServer进程中。然后关闭Zygote进程fork带来的Socket对象。3.然后调用handleSystemServerProcess方法,最后进入zygoteInit,对新进程做一些初始化工作。在zygoteInit方法中:4.commonInit方法是为进程做一些常用的初始化工作,比如设置时区、重置日志配置等。5、nativeZygoteInit方法会通过JNI去到native层。主要工作是创建一个新的Binder线程池,以便SystemServer可以与主要的app进程通信。6、applicationInit方法最终会走到findStaticMain方法,通过反射调用SystemServer类的main方法,简单贴上代码:protectedstaticRunnablefindStaticMain(StringclassName,String[]argv,ClassLoaderclassLoader){Classcl;try{cl=Class.forName(className,true,classLoader);}//...Methodm;try{m=cl.getMethod("main",newClass[]{String[].class});}//...returnnewMethodAndArgsCaller(m,argv);}工作的SystemServer进程被创建,一些初始化工作已经完成,接下来是main方法。顾名思义,主体工作必须开始。publicstaticvoidmain(String[]args){newSystemServer().run();}privatevoidrun(){try{//...//1android.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);//2System.loadLibrary("android_servers");//3performPendingShutdown();//4createSystemContext();//5mSystemServiceManager=newSystemServiceManager(mSystemContext);mSystemServiceManager.setStartInfo(mRuntimeRestart,mRuntimeStartElapsedTime,mRuntimeStartUptime);LocalServices.addService(SystemServiceManager.class,mSystemServiceManager);//准备可以并行化的初始化任务的线程池SystemServerInitThreadPool.get();}finally{traceEnd();}//。..//Startservices.try{//6startBootstrapServices();//7startCoreServices();//8startOtherServices();SystemServerInitThreadPool.shutdown();}//...//Loopforever.Looper.loop();thrownewRuntimeException("Mainthreadloopunexpectedlyexited");}1.准备主线程,Looper2.加载动态库。3、检测上次关机过程是否失败。4.初始化系统上下文。privatevoidcreateSystemContext(){ActivityThreadactivityThread=ActivityThread.systemMain();mSystemContext=activityThread.getSystemContext();mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);finalContextsystemUiContext=activityThread.getSystemUiContext();systemUiContext.setTheme(DEFAULT_SYSTEM);}_TActivityThread类获取上下文并设置一些系统主题。5、创建SystemServiceManager,用于后续创建系统服务管理。run方法最后的工作就是启动三类服务,这也是我们关注的重点,分别是引导服务、核心服务和其他服务。这些服务有100多种,关系到整个Android应用生态系统。让我们在下面详细讨论它们。6.启动bootstrap服务privatevoidstartBootstrapServices(){//安装APK服务traceBeginAndSlog("StartInstaller");Installerinstaller=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的安装、分析和卸载);mFirstBoot=mPackageManagerService.isFirstBoot();mPackageManager=mSystemContext.getPackageManager();traceEnd();//...}在启动服务中,有几个我们比较熟悉的,比如AMS和PMS。7.启动核心服务privatevoidstartCoreServices(){traceBeginAndSlog("StartBatteryService");//管理电池相关服务mSystemServiceManager.startService(BatteryService.class);traceEnd();//收集用户使用时间servicetraceBeginAndSlog("StartUsageService");mSystemServiceManager.startService(UsageStatsService.class);mActivityManagerService.setUsageStatsManager(LocalServices.getService(UsageStatsManagerInternal.class));traceEnd();//Webview更新服务if(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)){traceBeginAndSlog("ServiceStartWebView;Update")mWebViewUpdateService=mSystemServiceManager.startService(WebViewUpdateService.class);traceEnd();}//...}8.启动其他服务privatevoidstartOtherServices(){//...//电话管理服务traceBeginAndSlog("StartTelephonyRegistry");telephonyRegistry=newTelephonyRegistry(context);ServiceManager.addService("telephony.registry",telephonyRegistry);traceEnd();//WMS,窗口管理服务,是al所以更复杂的traceBeginAndSlog("StartWindowManager服务”);ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart,START_SENSOR_SERVICE);mSensorServiceStart=null;wm=WindowManagerService.main(context,inputManager,mFactoryTestMode!=FactoryTest.FACTORY_TEST_LOW_LEVEL,!mFirstBootService,mOnlyCore,newPheroneW(text)WINDOW_/*SERVICE,wlatedIlated=*/false,DUMP_FLAG_PRIORITY_CRITICAL|DUMP_FLAG_PROTO);ServiceManager.addService(Context.INPUT_SERVICE,inputManager,/*allowIsolated=*/false,DUMP_FLAG_PRIORITY_CRITICAL);traceEnd()log/"StartInputManager");inputManager.setWindowManagerCallbacks(wm.getInputMonitor());inputManager.start();traceEnd();//...}启动了这么多服务,我们来看看服务是如何启动的:publicTstartService(ClassserviceClass){try{finalStringname=serviceClass.getName();//创建service.finalTservice;try{Constructorconstructor=serviceClass.getConstructor(Context.class);service=constructor.newInstance(mContext);}//...startService(service);returnservice;}finally{Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);}}//所有系统服务的集合privatefinalArrayListmServices=newArrayList();publicvoidstartService(@NonNullfinalSystemServiceservice){//Registerit.mServices.add(service);//Startit.longtime=SystemClock.elapsedRealtime();try{service.onStart();}catch(RuntimeExceptionex){thrownewRuntimeException("Failedtostartservice"+service.getClass().getName()+":onStartthrewanexception",ex);}warnIfTooLong(SystemClock.elapsedRealtime()-time,service,"onStart");}可以看到首先通过反射创建了对应的Service类,然后将对应的Service添加到mServices集合中,完成注册后调用onStart方法启动对应的Service,完成初始化工作。至此,SystemServer的启动完成。我们回顾一下这个过程,它到底做了什么?Zygote首先fork了SystemServer的子进程,然后关闭了原来的socket,并新建了一个Binder线程池。其次,做了一些初始化工作,创建了Context对象,创建了SystemServiceManager类来管理所有的系统服务。最后启动三类系统服务,分别是引导服务、核心服务和其他服务。系统知识扩展Socket和Binder我们注意到,在SystemServerfork之后,有一个操作是关闭Sokcet,启动Binder线程池进行进程间通信。问题来了,为什么Zygote进程使用Socket进行通信,而SystemServer进程使用Binder进行通信呢?其实这是两个问题。第一个问题是问Android为什么要使用Binder进程与系统服务通信?这就涉及到Binder的知识了。之所以设计Binder,是因为它有两个不同于其他IPC方式的优点:高性能和高效率:传统IPC(套接字、管道、消息队列)需要copy内存两次,Binder只需要copy一次内存,而共享内存不需要复制内存。安全性好:接收方可以从数据包中获取发送方的进程ID和用户ID,便于验证发送方的身份。其他IPC如果想做实验只能主动保存,但是这个在发送过程中可能会被修改。第二个问题,为什么Zygote进程使用Socket而不是Binder进行通信呢?这也是wanAndroid中的一个问题:每日一问|在Activity启动过程中,大多使用Binder进行通信。他们为什么要与Zygote通信?你想使用套接字吗?(https://www.wanandroid.com/wenda/show/10482)评论区主要有以下观点:ServiceManager不能保证在zygoteup的时候已经初始化,所以不能使用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,负责窗口的启动、添加、删除等工作。参考https://www.wanandroid.com/wenda/show/10482https://blog.csdn.net/yiranfeng/article/details/103550262