一、背景

在鸿蒙开发中提供了两种多线程并发方案,分别是TaskPool与Worker,此篇文章主要总结下Worker

二、Worker概念

1、Worker为应用程序提供一个多线程的运行环境,实现后台线程与宿主线程分离

2、Worker有自己的生命周期,一旦创建不会主动销毁,需手动销毁空闲的Worker

3、作用:在后台线程中处理耗时操作(如:计算密集型或高延迟任务),避免影响主线程(如:UI主线程)

4、目标:将「重量级、长期、有状态」的耗时逻辑从主线程剥离,解决主线程被阻塞导致 UI 无响应的问题

5、运作机制

Worker子线程和宿主线程通过消息传递机制通信,利用序列化、引用传递或转移所有权的机制完成命令和数据的交互

三、注意事项

1、创建Worker

A、自动创建:使用DevEco Studio 单击鼠标右键 > New > Worker,一键生成Worker的模板文件及配置信息

B、手动创建:在工程目录下创建Worker文件,并在build-profile.json5配置Worker文件路径

//Stage模型:
"buildOption": {
  "sourceOption": {
    "workers": [
      "./src/main/ets/workers/worker.ets"
    ]
  }
}

2、文件路径

A、Stage模型--->路径规则:{moduleName}/ets/{relativePath}

1. // worker线程文件所在路径:"entry/src/main/ets/workers/worker.ets"
2. const workerStage1: worker.ThreadWorker = new worker.ThreadWorker('entry/ets/workers/worker.ets');

B、HAR包中加载Worker线程文件--->路径规则:@{moduleName}/ets/{relativePath}

1. // @标识路径加载形式:
2. // worker线程文件所在路径: "har/src/main/ets/workers/worker.ets"
3. const workerStage4: worker.ThreadWorker = new worker.ThreadWorker('@har/ets/workers/worker.ets');

3、资源加载

A、同时运行的Worker子线程数量最多为64个(与napi_create_ark_runtime创建的runtime总数不超过80)

B、单次序列化传输的数据量大小限制为16MB

4、模块使用限制

A、只能使用线程安全的库,UI相关的非线程安全库不能使用

B、不支持在多个HAP之间共享使用相同的Worker线程文件

C、不支持在Worker工作线程中AppStorage

D、禁止使用export语法导出

5、异常处理

A、API 18+使用onAllErrors回调捕获异常,Worker线程继续存活

B、API 18以前使用onerror回调捕获异常,Worker线程进入销毁流程,无法继续使用

四、Worker生命周期

生命周期顺序:创建--->运行--->销毁

1、创建阶段

在主线程或父Worker线程中,调用new worker.ThreadWorker(scriptURL)

2、运行阶段

通过 postMessage 和 onmessage 与创建它的线程进行双向通信。

  • 核心方法:

    • parentPort.postMessage(): 发送消息。

    • parentPort.onmessage(): 接收消息。

    • onerror(): 处理错误。

3、销毁阶段

由创建该Worker的线程(父线程)主动调用 worker.terminate()

  • terminate():立即终止

  • close():正常关闭

关键点:必须手动触发。对于多级Worker,必须严格遵循 “从子到父”的销毁顺序(即先销毁所有子Worker,再销毁父Worker)

五、怎么用

背景:结合项目中需求来看怎么用,目前我们项目是用worker线程来实现sse长链接

步骤1:配置构建文件

打开 模块的build-profile.json5 文件,在 buildOption 字段内添加 sourceOption 配置:

作用:保证系统能找到新建的Worker脚本

步骤2:创建Worker后台脚本

在 src/main/ets/ 目录下,创建 workers 文件夹并创建脚本文件

如:/src/main/ets/workers/xxx.ets

作用:这是 Worker 线程的 “入口文件”,负责和主线程通信,接收主线程的指令,并调度 Worker 内部的业务逻辑

步骤3:在 Worker 内部实现 SSE 长连接核心逻辑

作用:负责完整实现 SSE 连接的建立、心跳维持、消息处理、异常重连等核心功能

A、SSE 连接启动与初始化

B、SSE 消息处理与心跳维持

C、异常重连机制

步骤 4:主线程触发 SSE 启动

作用:在 UI 主线程(@Component 组件)中,封装 SSE 配置,触发 Worker 启动,注册消息处理器

在UI主线程中的aboutToAppear中启动SSE

六、适用场景

A、长耗时任务:执行时间 > 10秒(如大插件解压)

B、长期运行的后台服务(如音乐播放器、实时定位追踪)

C、频繁双向通信(如实时聊天的消息处理)

D、需指定专属线程(避免切换、绑定特性)

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐