3.3.appspawn的初始化

AppSpawn是一个独立的进程,由init进程初始化阶段拉起。AppSpawn是应用孵化器,作用是Fork出AbilityMain进程。整个系统框架图如下:

78fbd9392311eedf00ab04396460997f.png

前面的分布式调度中有介绍最后通过ams拉起FA,ams则是通过AppSpawn来孵化出(Fork出)一个AbilityMain进程。而AbilityMain就是JS应用的native实例,里面包含了ACE(JS应用开发框架,其中调用的JerryScript引擎跑JS代码)、graphic_ui部件等。另外AbilityMain还通过IPC通讯到wms_server进程(这个进程也是通过init进程拉起的服务),wms_server进程管理窗口和输入。

上面的图中只有AbilityMain是由AppSpawn拉起的,其他都是由init拉起的系统服务。反过来说AppSpawn只负责拉起AbilityMain进程,是所有AbilityMain(应用进程)的父进程。

AppSpawn的代码路径:base/startup/services/appspawn_lite

目录结构:

c83e4ed4455c3aaef856dd0067a97176.png

下面我们看下AppSpawn进程的初始化过程,从main.c的main()函数开始,代码如下:

46b34e0dc5ae0dea361ce91c0dfa02b1.png

代码主要分三个部分:

1、初始化系统服务框架,初始化AppSpawn服务

2、注册SIGCHLD

3、进入死循环

其中注册的SIGCHLD的处理函数SignalHandler()函数代码如下:

877a61e3c057adb358fe7457ba61026d.png

上面的代码可以看到在Ability退出后,AppSpawn作为父进程收到了SIGCHLD信号,但是什么都没做。

所以我们重点分析下HOS_SystemInit()函数,代码如下:

cca8754d70521d1f76f5398603bf5f09.png

实际上上述代码是一个标准的形式,在wms_server和bundle_daemon服务中都会有类似的函数,都是调用了SAMGR_Bootstrap(),这个地方就是初始化系统服务子系统的框架。我们在《分布式调度子系统》中有过初步分析,这里不再详细介绍。samgr框架初始化过程中会初始化注册的服务,在我们的AppSpawn中,注册的服务在appspawn_service.c中,代码如下:

a294a3b2cd02fd1000482b94cedd3ca7.png

SYSEX_SERVICE_INIT()宏定义在.\utils\native\lite\include\ohos_init.h中,与以前介绍过的SYS_SERVICE_INIT()宏类似,这里不再做详细介绍。由这个宏定义的函数,会在main()函数调用前被执行。

我们来看看AppSpawnInit()函数的实现,主要就是向samgr注册了服务和Feature。注册的服务结构体如下:

3bc039d88ece6f70a43b4797a703e07b.png

其中的Initialize()会在初始化阶段被调用。Invoke会在远程IPC中被调用。

我们先看看Initialize()函数,下一节分析下Invoke()函数。

fa62832f7b141f098b62d4968a302f9f.png

看起来只是设置了服务的标识符,其他没做什么。

3.4.appspawn的孵化流程

在分布式调用拉起FA的流程中,dms(分布式调度子系统)通过ams(Ability Manager Service)来拉起FA,最终调用的是 amsInterface->StartAbility()函数。这里的amsInterface就是ams服务的FeatureApi接口。在AMS中,最终通过AppManager::StartAppProcess()函数(foundation\aafwk\services\abilitymgr_lite\src\app_manager.cpp)通过调用AppSpawnClient::SpawnProcess()函数(foundation\aafwk\services\abilitymgr_lite\src\client\app_spawn_client.cpp)来实现IPC远程调用到AppSpawn服务中。这个过程在其他文章中有涉及,这里不再介绍。

AppManager::StartAppProcess()函数部分代码如下:

3558b54a6eb48abb1156e20308fe371d.png

代码中可以看出最终调用了Invoke。实际上是通过IClientProxy->Invoke()远程调用到了IServerProxy->Invoke()。而在Server端的Invoke实现就是appspawn_serivce.c中的Invoke()函数。代码如下:

71fbe40f49c09a5f15a9c5e8e196b072.png

代码分三个部分:

1、参数校验:参数的funcId必须是ID_CALL_CREATE_SERVICE,这与AppManager::StartAppProcess()函数中的调用是一致的。

2、IPC的消息接收和解析:这部分大家自己看一下。

3、功能实现:调用CreateProcess()函数

下面我们看下CreateProcess()的代码:

20763d497206676128f206ec927b4872.png

这个代码与init进程中ServiceStart()函数实现基本结构一致,都是fork()出一个子进程,然后在子进程中调用execve()加载可执行程序。区别是这里加载的可执行程序是写死的ABILITY_EXE_FILE_FULL_PATH宏,定义为"/bin/abilityMain"(由foundation/aafwk/frameworks/ability_lite目录编译出来)。因此,结论就是AppSpawn的唯一任务就是fork出abilityMain进程,而这个abilityMain是所有js应用的native载体,负责Ability的生命周期管理、JerryScript引擎的加载、App中的JS的加载和初始化、JS中定义的component组件的创建和事件的对接等等。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐