鸿蒙多进程能力实战分析

223 阅读3分钟

一、背景:

在项目开发中遇到一个多进程的场景。

项目初始阶段为一个单进程,所有业务逻辑均在该进程中执行。但是随着业务的演进,且受到内存等资源基线的限制,项目需要拆分为多个进程,然后在子进程成执行资源占有较多的任务,降低主进程的资源消耗。

为此,需要实现一套“多进程定义以及任务调度的框架”。

二、技术分析

2.1 申请系统权限

在OpenHarmony中,一个应用默运行在一个进程中。若要开启多进程能力,则需要向系统申请特权。

官方文档详见:《应用特权配置指南》

本地调试(需要ROOT)时的具体步骤为:

  1. 拉取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
  1. 新增配置项

        {
          "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来定义子进程的信息。

具体步骤为:

  1. 创建Feature类型Module...略

image.png

  1. 定义子进程的进程名称
    在Feature类型的Module中的 module.json5 中的声明“process”字段

  2. 定义子进程的入口 在Feature类型的Module中,新增ServiceExtensionAbility类型的组件

image.png

2.3 发起调用

在项目的主进程中,可以按需发起IPC调用,实现多进程的交互。

详见官方文档:《# ServiceExtensionContext (系统接口)》

三、关键技术点

3.1 按需销毁子进程

在项目中,子进程用来执行部分销毁资源的任务。因此子进程在执行完任务后需要按需结束,而不应该长时间运行。

同时,也应该避免在短时间内频繁“拉起-关闭”子进程,否则也会增加系统的资源消耗。

因此,需要涉及一套“销毁子进程”的规则。

大致思路为:

  1. 子进程中会创建多个Task,且子进程持有每个Task的对象(存入Set中)
  2. 每个Task 空闲时间默认为 10s(支持自定义设置空闲时间)
  3. 一个子进程中仅创建一个全局Timer,执行以下逻辑:
    • 在子进程中遍历Set中的Task:找到所有Task“剩余的空闲时间”,然后设置Timer的超时时间;
    • 超时后,再次执行遍历;
    • 若所有Task的“剩余空闲时间”均为0,则断开链接

一句话概括:
Timer 不断询问每一个Task:如果所有Task均执行完毕,则结束子进程

3.2 仅在子进程中import Task

为了降低主进程的内存占用,需要将占用内存资源的任务调度到子进程中执行。

因此,在主进程中应该避免 import 无关的类和变量等。

另外,对于时延敏感的Task,不应该调度到子进程中执行。因为IPC建链过程会增加耗时。

3.3 如何在子进程中实例化Task对象

详见:《使用TS如何在子进程中动态实例化一个对象》