harmonyos samgr,#2020征文-其它#HarmonyOS启动恢复之init和AppSpawn(下)
3.3.appspawn的初始化AppSpawn是一个独立的进程,由init进程初始化阶段拉起。AppSpawn是应用孵化器,作用是Fork出AbilityMain进程。整个系统框架图如下:前面的分布式调度中有介绍最后通过ams拉起FA,ams则是通过AppSpawn来孵化出(Fork出)一个AbilityMain进程。而AbilityMain就是JS应用的native实例,里面包含了ACE(JS
3.3.appspawn的初始化
AppSpawn是一个独立的进程,由init进程初始化阶段拉起。AppSpawn是应用孵化器,作用是Fork出AbilityMain进程。整个系统框架图如下:

前面的分布式调度中有介绍最后通过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
目录结构:

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

代码主要分三个部分:
1、初始化系统服务框架,初始化AppSpawn服务
2、注册SIGCHLD
3、进入死循环
其中注册的SIGCHLD的处理函数SignalHandler()函数代码如下:

上面的代码可以看到在Ability退出后,AppSpawn作为父进程收到了SIGCHLD信号,但是什么都没做。
所以我们重点分析下HOS_SystemInit()函数,代码如下:

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

SYSEX_SERVICE_INIT()宏定义在.\utils\native\lite\include\ohos_init.h中,与以前介绍过的SYS_SERVICE_INIT()宏类似,这里不再做详细介绍。由这个宏定义的函数,会在main()函数调用前被执行。
我们来看看AppSpawnInit()函数的实现,主要就是向samgr注册了服务和Feature。注册的服务结构体如下:

其中的Initialize()会在初始化阶段被调用。Invoke会在远程IPC中被调用。
我们先看看Initialize()函数,下一节分析下Invoke()函数。

看起来只是设置了服务的标识符,其他没做什么。
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()函数部分代码如下:

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

代码分三个部分:
1、参数校验:参数的funcId必须是ID_CALL_CREATE_SERVICE,这与AppManager::StartAppProcess()函数中的调用是一致的。
2、IPC的消息接收和解析:这部分大家自己看一下。
3、功能实现:调用CreateProcess()函数
下面我们看下CreateProcess()的代码:

这个代码与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组件的创建和事件的对接等等。
更多推荐


所有评论(0)