一、背景:
在项目开发中遇到一个多进程的场景。
项目初始阶段为一个单进程,所有业务逻辑均在该进程中执行。但是随着业务的演进,且受到内存等资源基线的限制,项目需要拆分为多个进程,然后在子进程成执行资源占有较多的任务,降低主进程的资源消耗。
为此,需要实现一套“多进程定义以及任务调度的框架”。
二、技术分析
2.1 申请系统权限
在OpenHarmony中,一个应用默运行在一个进程中。若要开启多进程能力,则需要向系统申请特权。
官方文档详见:《应用特权配置指南》
本地调试(需要ROOT)时的具体步骤为:
- 拉取ROM的配置文件
// ${type} 可能为 phone/table 等
hdc file recv /system/variant/${type}/base/etc/app/install_list_capability.json
// 如:
hdc file recv /system/variant/phone/base/etc/app/install_list_capability.json
- 新增配置项
{
"bundleName": "xxxxxx", // 包名
"app_signature": [
"xxxx" // 给hap包签名的证书指纹
],
// 允许应用使用ServiceExtension、DataExtension
"allowAppUsePrivilegeExtension": true
//允许应用多实例
"allowAppMultiProcess": true
}
2.2 定义子进程
在OpenHarmony中,HAP是应用安装的基本单位。HAP可以分为Entry和Feature两种类型。
- Entry类型的HAP:应用的主模块。。
- Feature类型的HAP:应用的动态特性模块。一个App可以包含零个、一个或多个Feature类型的HAP。
默认情况下,entry模块为主进程。所以需要创建一个Feature类型的Module来定义子进程的信息。
具体步骤为:
- 创建Feature类型Module...略
-
定义子进程的进程名称
在Feature类型的Module中的module.json5中的声明“process”字段 -
定义子进程的入口 在Feature类型的Module中,新增
ServiceExtensionAbility类型的组件
2.3 发起调用
在项目的主进程中,可以按需发起IPC调用,实现多进程的交互。
详见官方文档:《# ServiceExtensionContext (系统接口)》
三、关键技术点
3.1 按需销毁子进程
在项目中,子进程用来执行部分销毁资源的任务。因此子进程在执行完任务后需要按需结束,而不应该长时间运行。
同时,也应该避免在短时间内频繁“拉起-关闭”子进程,否则也会增加系统的资源消耗。
因此,需要涉及一套“销毁子进程”的规则。
大致思路为:
- 子进程中会创建多个Task,且子进程持有每个Task的对象(存入Set中)
- 每个Task 空闲时间默认为 10s(支持自定义设置空闲时间)
- 一个子进程中仅创建一个全局Timer,执行以下逻辑:
- 在子进程中遍历Set中的Task:找到所有Task“剩余的空闲时间”,然后设置Timer的超时时间;
- 超时后,再次执行遍历;
- 若所有Task的“剩余空闲时间”均为0,则断开链接
一句话概括:
Timer 不断询问每一个Task:如果所有Task均执行完毕,则结束子进程
3.2 仅在子进程中import Task
为了降低主进程的内存占用,需要将占用内存资源的任务调度到子进程中执行。
因此,在主进程中应该避免 import 无关的类和变量等。
另外,对于时延敏感的Task,不应该调度到子进程中执行。因为IPC建链过程会增加耗时。