【Android】system_server 创建和启动流程

SystemServer进程的创建和启动流程

在将SystemServer的启动流程之前,先回顾一下上一篇章的内容:

上篇文章中,我们介绍了从init进程到zygote进程再到SystemServer进程开始创建的流程,大致是这样的:

1、执行app_main.cpp文件的main方法(init进程中)

2、main方法中初始化AndroidRuntime

3、执行runtime.start()启动Android运行时环境,其中,start()方法内部通过startVM方法创建了虚拟机,通过startReg方法注册JNI

4、然后通过jni方法调用ZygoteInit的main()方法,由此从native层进入到了java层

5、ZygoteInit的main()方法做了以下几件事情:

(1)执行了preload()方法,对部分资源进行了预加载

(2)创建zygote进程的socket服务(此时binder还未创建)

(3)调用forkSystemServer()方法,创建了system_server进程

那么,我们接着上一篇章的内容,继续说下SystemServer的创建和启动流程。

SystemServer的创建流程

个人认为,SystemServer的创建流程不算特别重要,如果不想看的同学,可以直接跳过,去看SystemServer的启动流程。

我们先看到上一篇文章中的最后一张图:

【Android】system_server 创建和启动流程_第1张图片

我们已经知道,通过forSystemService()方法创建出了SystemService进程,这就是SystemServer进程的创建入口,我们进入forkSystemServer()这个方法中看看,下面这段代码位于forkSystemServer()方法中:

【Android】system_server 创建和启动流程_第2张图片

在这个方法里,通过fork创建出system_server进程,并返回pid值,然后让fork出来的子进程,也就是system_server进程,去执行handleServerProcess()方法。

这里细心的同学可能会有疑问,为什么pid等于0就是子进程执行的?????

其实,了解进程的fork机制的话,可能就很容易理解了,fork可以理解为分裂,分裂后有出现两个代码一模一样的进程,分裂出来后就会同时执行这两个进程的代码。既然代码一模一样,那我怎么知道我当前执行的代码是位于父进程的,还是是子进程的呢。

在java机制中,如果是父进程中执行的fork,返回值将会是分裂出的子进程的进程号(pid);如果是子进程中执行的fork,它的返回值将会是0,或者说是无效值。所以,通过fork方法的返回值,我们就可以判断,当前所处的进程是子进程还是父进程。

接下来我们跟进**handleServerProcess()**方法,看看里面做了什么,

先有个心里准备,下面这段代码跟进的层级有点深,但我们只要关注比较核心的部分就行了,核心的地方都有注释,大家放心食用,下面开始出发:

【Android】system_server 创建和启动流程_第3张图片

【Android】system_server 创建和启动流程_第4张图片

【Android】system_server 创建和启动流程_第5张图片

【Android】system_server 创建和启动流程_第6张图片

【Android】system_server 创建和启动流程_第7张图片

好了,终于结束了!!!通过以上代码的一步一步跟进,我们已经知道,在ZygoteInit.java类中,通过调用forkSystemServer()方法,会fork出SystemService进程,然后SystemService进程内部会通过反射拿到SystemServicemain方法,并将main方法的invoke放在一个Runnable类的run方法中执行,最终将这个Runnable对象通过forkSystemServer()方法返回,所以说,forkSystemServer()的返回值就是个Runnable对象了。

拿到这个Runnable对象后,就开始调用run方法,也就是相当于执行SystemService的main方法了。

有了这个基础,接下来,

我们再回到ZygoteInit的main方法中,看到开头的那一段代码:

【Android】system_server 创建和启动流程_第8张图片

如果r不为null,就执行r.run()方法。

这里要注意的是,r不为null,其实就说明当前处于systemService进程中,执行了run()就可以直接return了。因为下面的代码就不是SystemService进程需要执行的了,那是zygote进程要执行的。如果r为null,那就是处于zygote进程中。

为了方便大家理解,在这里贴一张SystemServer进程创建过程的流程图:
【Android】system_server 创建和启动流程_第9张图片

SystemServer的启动流程

SystemServer的启动过程中,还启动了很多比较重要的服务,例如ATM服务,AMS服务,PMS服务、PKMS服务、WMS服务等。

同时桌面的启动也是在这进行。所以说,SystemServer的启动流程相对来说还是比较重要的。

下面我们进入正题,在上面的流程中,我们知道,当fork出了SystemServer进程,然后执行r.run()方法,其实内部执行就是SystemServer的main方法。

下面我们直接看SystemServer的main方法:

【Android】system_server 创建和启动流程_第10张图片

可以看到,SystemServer的main方法又直接执行了SystemServer的run方法,所以我们直接进入run方法看看:

【Android】system_server 创建和启动流程_第11张图片

在run方法中,我们首先可以看到,在这个方法中对SystemServiceManaager进行了初始化。

SystemServiceManaager这个对象是一个比较重要的对象,它是用来管理SystemService进程的,同时,它还用来启动了其他服务,我们后面会再讲到这个对象。

我们接着往run方法往下看:

【Android】system_server 创建和启动流程_第12张图片

可以看到,run方法中,还执行了三个方法:

startBootStrapServices(t):对应系统引导服务。我们熟悉的ATM、AMS、PMS、PKMS服务就是在这启动的。

startCoreServices(t):对应核心服务。如电池服务就是在这启动。

startOtherServices(t):对应其他服务。在这个方法中,启动的服务大概有70+个,WMS服务就是在这里启动的。

下面我们先进入startBootStrapServices方法:

【Android】system_server 创建和启动流程_第13张图片

可以看到在startBootStrapServices中,分别启动了ATM服务(ActivityTaskManagerService)和AMS服务(ActivityManagerService)。注意在Android10之前,这块代码是直接就启动AMS服务的。在Android10之后,这里才多启动了一个ATM服务。

**SystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getServcice()**这个方法,内部是通过反射来获取到atm对象的。getServcice()这个方法我们就不详细跟进了。

我们看ActivityTaskManagerService.Lifecycle这个类吧,进去看看里面是什么:

【Android】system_server 创建和启动流程_第14张图片

可以看到,它是ATM(ActivityTaskManagerService)的一个内部类,并且继承自SystemService。

在Lifecycle构造方法中,通过new创建了ATM对象。

在它的onStart()方法中,调用了publishBinderService()这个方法,publishBinderService方法的内部实际上调用了ServiceManager.addService()方法,通过这个方法,就把ATM这个服务保存在ServiceManager中了。

那么,ATM这个服务在创建的时候又干了些什么呢?我们跟进ATM的构造方法看看:

【Android】system_server 创建和启动流程_第15张图片

可以看到,在ATM的构造方法中,通过*new ClientLifecycleManager()*创建了acitivity的生命周期管理类。

好了,启动ATM服务的过程我们就先介绍到这里,下面我们继续让下看。

ATM服务创建完后,接着就到AMS的启动了,下面这段代码就是启动AMS服务的入口:

【Android】system_server 创建和启动流程_第16张图片

可以看到,是通过**ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm)**这个方法启动AMS的,下面,我们继续跟进代码,进入Lifecycle.startService方法:

【Android】system_server 创建和启动流程_第17张图片

可以看到,实际上,这个方法内部跟ATM的启动方式是一样的,都是调用了**SystemServiceManager.startService(Lifecycle.class).getServcice()**这个方法。

同时,我们可以看到,在Lifecycle的构造函数中,创建了一个AMS对象。我们进入看看AMS的创建内部干啥了:

【Android】system_server 创建和启动流程_第18张图片

可以看到,内部有段代码调用了atm服务的initialize()方法,我们继续跟进这个方法:
【Android】system_server 创建和启动流程_第19张图片

可以看到,initialize方法中,通过createStackSuppervisor()方法创建出了栈管理对象(mStackSupervisor)。

然后又通过,setRecentTacks(new RecentTasks(this, mStackSupervisor))来设置当前用户栈,这个用户栈的意思就是APP切到后台后,仍可以存活,保存在这个栈中,等待用户随时调起。

ok,AMS的创建所做的事情就大概了解这个多吧。我们需要关注的是,AMS的创建主要就是创建出了一个后台应用的栈管理对象。

那么,AMS服务是怎么添加到ServiceManager中的呢?我们继续往下看代码:

【Android】system_server 创建和启动流程_第20张图片

AMS会调用一个**setSystemProcess()**这个方法,这个方法内部是干嘛的呢?我们来看看:

【Android】system_server 创建和启动流程_第21张图片

可以看到,通过ServiceManager.addService()方法,把当前的ams对象保存进了ServiceManager中。当然,这里除了保存AMS服务到ServiceManager中,还保存了其他的服务,例如,meminfo、dbinfo等等,其实,他们都是一个个的binder服务。

下面我再来大致的看一下,WMS是在哪里的启动的呢

由上面的流程图中,我们知道,WMS服务的启动是在startOtherServices方法中进行的。我们直接定位到wms启动的代码行看看:

【Android】system_server 创建和启动流程_第22张图片

可以看到,它是通过WindowMangerService.main()的方式去创建的。其实在Android 10之前,我们的AMS的创建方式也是通过这种.main的方式去创建的,只是说,后面增加了一个ATM服务后,就进行了一些改造而已。

然后,又通过setWindowManger(wm)方法将WMS服务和AMS服务进行了关联。

我们再看看启动桌面的流程

当我们启动了AMS服务后,会通过调用ams的systemReady()方法,来启动桌面。这个流程比较简单,我们也不详细说了,直接看代码吧:

【Android】system_server 创建和启动流程_第23张图片

OK,SystemServer的启动流程我们就大概介绍到这里,我们最后来做个总结吧。

SystemServer的启动流程:

1、首先,执行SystemServer的main方法,main方法内部又执行了run方法

2、创建出一个SystemServerManager对象

3、执行三个方法:startBootStrapServices、startCoreServices、startOtherServices,分别启动系统引导服务、核心服务、其他服务

4、其中,startBootStrapServices中,启动了ATM服务,和AMS服务。启动ATM服务的过程中,创建出了acitivity的生命周期管理对象;启动AMS的过程中,创建了栈管理对象。ATM服务是通过ServiceManager.addService()方法保存在ServiceManager中的;AMS服务是通过setSystemProcess方法ServiceManager中的。startOtherServices方法中,又启动了WMS服务,以及启动了桌面。

下面,也贴出一张图方便大家理解:

【Android】system_server 创建和启动流程_第24张图片

那么,了解这些启动流程到底有什么用啊???这不都是Android系统内部实现好的吗,跟我一个Android应用层的开发工程师有什么关系呢?我们平时开发应用又不需要知道这些东西。

况且!!!即使我不知道这些东西,还不是能正常开发出一个很棒的应用出来。

确实,对这些启动流程没有任何了解也不影响正常开发应用,也不影响你是个Android开发工程师。但是我认为,作为一名程序员,还是要对自己的技术的深度和广度有些要求才是最好的。另一方面,当我们对这些启动流程有了一定的了解后,这对于我们在应用中解决问题也是非常有帮助的。就比如ANR问题,我们就是要对AMS的启动流程比较熟悉的情况下,才能更容易的定位和解决问题。

你可能感兴趣的:(Android基础知识,android,java)