这篇文章主要讲解了“什么是SystemServer进程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么是SystemServer进程”吧!
创新互联公司主要从事网站设计、成都网站制作、网页设计、企业做网站、公司建网站等业务。立足成都服务昌江黎族,十多年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:028-86922220
诞生
之前在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(); //... }
启动了这么多服务,我们再看一下服务都是怎么具体启动的:
publicT startService(Class serviceClass) { try { final String name = serviceClass.getName(); // Create the service. final T service; try { Constructor constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext); } //... startService(service); return service; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } // 所有系统服务的集合 private final ArrayList mServices = new ArrayList (); 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进程这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!