|
|
|
|
公众号矩阵

系统中的大管家—SystemServer进程

这个进程负责启动和管理JavaFramework层,也就是提供了框架层的很多服务,比如我们熟知的AMS,PMS,WMS,还有DisplayManagerService、CameraService等等,也就是说它掌握了Android系统中的命脉,是Android系统中的大管家。

作者: 积木zz 来源: 码上积木 |2021-01-08 08:21

本文转载自微信公众号「码上积木」,可以通过以下二维码关注。转载本文请联系码上积木公众号。

前言

上篇说到Android系统的启动流程,Zygote进程fork的第一个进程就是SystemServer进程。

这个进程负责启动和管理JavaFramework层,也就是提供了框架层的很多服务,比如我们熟知的AMS,PMS,WMS,还有DisplayManagerService、CameraService等等,也就是说它掌握了Android系统中的命脉,是Android系统中的大管家。

一起瞅瞅吧~

(本文源码基于Android9.0)

诞生

之前在Android系统的启动过程中???说到,SystemServer进程是由Zygote进程fork而来。

fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,可以理解为COPY了一个进程出来,而这个新进程就是它的子进程。

而关于SystemServer的诞生,还要从ZygoteInit的forkSystemServer方法说起...(只保留主要代码)

  1. private static Runnable forkSystemServer(String abiList, String socketName, 
  2.            ZygoteServer zygoteServer) { 
  3.        //...  
  4.  
  5.        // 1 
  6.        int pid; 
  7.        pid = Zygote.forkSystemServer( 
  8.                    parsedArgs.uid, parsedArgs.gid, 
  9.                    parsedArgs.gids, 
  10.                    parsedArgs.runtimeFlags, 
  11.                    null
  12.                    parsedArgs.permittedCapabilities, 
  13.                    parsedArgs.effectiveCapabilities); 
  14.  
  15.        /* For child process */ 
  16.        if (pid == 0) { 
  17.            //2 
  18.            zygoteServer.closeServerSocket(); 
  19.            //3 
  20.            return handleSystemServerProcess(parsedArgs); 
  21.        } 
  22.  
  23.        return true
  24.    } 
  25.  
  26.    /** 
  27.     * Finish remaining work for the newly forked system server process. 
  28.     */ 
  29.    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) { 
  30.  
  31.            //...  
  32.  
  33.            /* 
  34.             * Pass the remaining arguments to SystemServer. 
  35.             */ 
  36.            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); 
  37.    } 
  38.  
  39.  
  40.    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { 
  41.        //... 
  42.  
  43.     //4  
  44.        RuntimeInit.commonInit(); 
  45.        //5 
  46.        ZygoteInit.nativeZygoteInit(); 
  47.        //6 
  48.        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); 
  49.    } 

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方法,简单贴下代码:
  1. protected static Runnable findStaticMain(String className, String[] argv, 
  2.            ClassLoader classLoader) { 
  3.        Class<?> cl; 
  4.  
  5.        try { 
  6.            cl = Class.forName(className, true, classLoader); 
  7.        }  
  8.        //... 
  9.  
  10.        Method m; 
  11.        try { 
  12.            m = cl.getMethod("main", new Class[] { String[].class }); 
  13.        }  
  14.        //... 
  15.       
  16.        return new MethodAndArgsCaller(m, argv); 
  17.    } 

工作

SystemServer进程创建出来了,并且做了一些初始化工作,接下来就来到了main方法了,顾名思义,肯定要开始正经主要的工作了。

  1. public static void main(String[] args) { 
  2.         new SystemServer().run(); 
  3.     } 
  4.  
  5.  
  6.     private void run() { 
  7.         try { 
  8.             //... 
  9.  
  10.             // 1 
  11.             android.os.Process.setThreadPriority( 
  12.                 android.os.Process.THREAD_PRIORITY_FOREGROUND); 
  13.             android.os.Process.setCanSelfBackground(false); 
  14.  
  15.             Looper.prepareMainLooper(); 
  16.             Looper.getMainLooper().setSlowLogThresholdMs( 
  17.                     SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); 
  18.  
  19.             // 2 
  20.             System.loadLibrary("android_servers"); 
  21.  
  22.             // 3 
  23.             performPendingShutdown(); 
  24.  
  25.             // 4 
  26.             createSystemContext(); 
  27.  
  28.             // 5 
  29.             mSystemServiceManager = new SystemServiceManager(mSystemContext); 
  30.             mSystemServiceManager.setStartInfo(mRuntimeRestart, 
  31.                     mRuntimeStartElapsedTime, mRuntimeStartUptime); 
  32.             LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); 
  33.             // Prepare the thread pool for init tasks that can be parallelized 
  34.             SystemServerInitThreadPool.get(); 
  35.         } finally { 
  36.             traceEnd();  
  37.         } 
  38.  
  39.         //... 
  40.  
  41.         // Start services. 
  42.         try { 
  43.             //6 
  44.             startBootstrapServices(); 
  45.             //7 
  46.             startCoreServices(); 
  47.             //8 
  48.             startOtherServices(); 
  49.             SystemServerInitThreadPool.shutdown(); 
  50.         }  
  51.  
  52.         //... 
  53.  
  54.         // Loop forever. 
  55.         Looper.loop(); 
  56.         throw new RuntimeException("Main thread loop unexpectedly exited"); 
  57.     }     
  • 1、准备主线程,Looper。
  • 2、加载动态库。
  • 3、检测上次关机过程是否失败。
  • 4、初始化系统上下文。
  1. private void createSystemContext() { 
  2.         ActivityThread activityThread = ActivityThread.systemMain(); 
  3.         mSystemContext = activityThread.getSystemContext(); 
  4.         mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); 
  5.  
  6.         final Context systemUiContext = activityThread.getSystemUiContext(); 
  7.         systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); 
  8.     } 

在这个方法中,创建了ActivityThread类,获取了上下文,并设置了一些系统主题。

  • 5、创建SystemServiceManager,用于后续的系统服务管理创建等工作。

run方法最后的工作就是启动三个服务类型的服务,也是我们重点关注的,分别是引导服务,核心服务,其他服务。

这些服务一共有100多个,关系着Android整个应用生态,下面我们具体说下。

  • 6、启动引导服务
  1. private void startBootstrapServices() { 
  2.  
  3.         //安装APK服务 
  4.         traceBeginAndSlog("StartInstaller"); 
  5.         Installer installer = mSystemServiceManager.startService(Installer.class); 
  6.         traceEnd(); 
  7.  
  8.         //AMS,负责四大组件的启动调度等工作 
  9.         mActivityManagerService = mSystemServiceManager.startService( 
  10.                 ActivityManagerService.Lifecycle.class).getService(); 
  11.         mActivityManagerService.setSystemServiceManager(mSystemServiceManager); 
  12.         mActivityManagerService.setInstaller(installer); 
  13.         traceEnd(); 
  14.  
  15.  
  16.         // 管理和显示背光LED等服务 
  17.         traceBeginAndSlog("StartLightsService"); 
  18.         mSystemServiceManager.startService(LightsService.class); 
  19.         traceEnd(); 
  20.  
  21.         //PMS,负责APK安装,解析卸载等工作 
  22.         traceBeginAndSlog("StartPackageManagerService"); 
  23.         mPackageManagerService = PackageManagerService.main(mSystemContext, installer, 
  24.                 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); 
  25.         mFirstBoot = mPackageManagerService.isFirstBoot(); 
  26.         mPackageManager = mSystemContext.getPackageManager(); 
  27.         traceEnd(); 
  28.  
  29.         //... 
  30.  
  31.     } 

引导服务中,有几个我们毕竟熟悉的,比如AMS、PMS。

  • 7、启动核心服务
  1. private void startCoreServices() { 
  2.         traceBeginAndSlog("StartBatteryService"); 
  3.         // 管理电池相关服务 
  4.         mSystemServiceManager.startService(BatteryService.class); 
  5.         traceEnd(); 
  6.  
  7.         // 收集用户使用时长服务 
  8.         traceBeginAndSlog("StartUsageService"); 
  9.         mSystemServiceManager.startService(UsageStatsService.class); 
  10.         mActivityManagerService.setUsageStatsManager( 
  11.                 LocalServices.getService(UsageStatsManagerInternal.class)); 
  12.         traceEnd(); 
  13.  
  14.         // Webview更新服务 
  15.         if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) { 
  16.             traceBeginAndSlog("StartWebViewUpdateService"); 
  17.             mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class); 
  18.             traceEnd(); 
  19.         } 
  20.  
  21.         //... 
  22.     } 
  • 8、启动其他服务
  1. private void startOtherServices() { 
  2.    //... 
  3.   
  4.             //电话管理服务 
  5.             traceBeginAndSlog("StartTelephonyRegistry"); 
  6.             telephonyRegistry = new TelephonyRegistry(context); 
  7.             ServiceManager.addService("telephony.registry", telephonyRegistry); 
  8.             traceEnd();     
  9.  
  10.  
  11.             //WMS,窗口管理服务,也是打交道比较多的 
  12.             traceBeginAndSlog("StartWindowManagerService"); 
  13.             ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE); 
  14.             mSensorServiceStart = null
  15.             wm = WindowManagerService.main(context, inputManager, 
  16.                     mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, 
  17.                     !mFirstBoot, mOnlyCore, new PhoneWindowManager()); 
  18.             ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false
  19.                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); 
  20.             ServiceManager.addService(Context.INPUT_SERVICE, inputManager, 
  21.                     /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); 
  22.             traceEnd(); 
  23.  
  24.  
  25.             //输入事件管理服务 
  26.             traceBeginAndSlog("StartInputManager"); 
  27.             inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); 
  28.             inputManager.start(); 
  29.             traceEnd();      
  30.  
  31.             //...      

启动了这么多服务,我们再看一下服务都是怎么具体启动的:

  1. public <T extends SystemService> T startService(Class<T> serviceClass) { 
  2.        try { 
  3.            final String name = serviceClass.getName(); 
  4.  
  5.            // Create the service. 
  6.            final T service; 
  7.            try { 
  8.                Constructor<T> constructor = serviceClass.getConstructor(Context.class); 
  9.                service = constructor.newInstance(mContext); 
  10.            } //... 
  11.            startService(service); 
  12.            return service; 
  13.        } finally { 
  14.            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); 
  15.        } 
  16.    } 
  17.  
  18.    // 所有系统服务的集合 
  19.    private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();     
  20.  
  21.    public void startService(@NonNull final SystemService service) { 
  22.        // Register it. 
  23.        mServices.add(service); 
  24.        // Start it. 
  25.        long time = SystemClock.elapsedRealtime(); 
  26.        try { 
  27.            service.onStart(); 
  28.        } catch (RuntimeException ex) { 
  29.            throw new RuntimeException("Failed to start service " + service.getClass().getName() 
  30.                    + ": onStart threw an exception", ex); 
  31.        } 
  32.        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart"); 
  33.    } 

可以看到,首先通过反射创建了对应的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,负责窗口启动,添加,删除等工作。

参考

《Android进阶解密》 https://www.wanandroid.com/wenda/show/10482 https://blog.csdn.net/yiranfeng/article/details/103550262

【编辑推荐】

  1. Android开发之Android Studio环境搭建视频课程
  2. 【李宁】移动开发实战之Android5.x新特性视频课程
  3. 【李宁】移动开发实战之Android5.x新特性视频课程
  4. 实现自己的Prisma(基于QT和OpenCV实现Android平台上基于AI的图像处理APP)
  5. 【李宁】定制Android ROM与刷Android6.0
【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

数据湖与数据仓库的分析实践攻略

数据湖与数据仓库的分析实践攻略

助力现代化数据管理:数据湖与数据仓库的分析实践攻略
共3章 | 创世达人

1人订阅学习

云原生架构实践

云原生架构实践

新技术引领移动互联网进入急速赛道
共3章 | KaliArch

30人订阅学习

数据中心和VPDN网络建设案例

数据中心和VPDN网络建设案例

漫画+案例
共20章 | 捷哥CCIE

209人订阅学习

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微