HarmonyOS ArkTS Worker 线程:独立执行环境详解
适用版本:HarmonyOS 6.1(API 12)及以上
验证环境:Pura 90 Pro 模拟器(HarmonyOS 6.1.1,API 24)
关键 API:@kit.ArkTS→worker.ThreadWorker、worker.workerPort
前言
上一篇我们用 TaskPool 完成了一次性并发任务,本篇聚焦 Worker——它的核心差异在于:Worker 是一个独立执行环境(独立 JS 引擎实例),拥有自己的内存空间,与主线程通过 postMessage 消息队列双向通信。适合长驻后台、需要持续交互的场景,如 WebSocket 数据处理、音频流解析、大文件边读边处理。
TaskPool vs Worker 核心对比
| 维度 | TaskPool | Worker |
|---|---|---|
| 生命周期 | 任务完成即结束 | 手动 terminate() |
| 通信方式 | 函数参数/返回值 | postMessage 消息队列 |
| 进度上报 | ❌ 不支持 | ✅ 随时 postMessage |
| 内存隔离 | 任务间隔离 | 与主线程完全隔离 |
| 适用场景 | 一次性计算 | 长驻/流式处理 |
| 线程数管理 | 系统自动 | 开发者控制 |
架构图
主线程(UI) Worker 线程(独立 JS 引擎)
│ │
│ new ThreadWorker('PrimeWorker.ets')│
│─────────────────────────────────── ▶│ Worker 初始化
│ │
│ postMessage({ limit: 300000 }) │
│─────────────────────────────────── ▶│ ctx.onmessage 触发
│ │ 开始筛质数…
│ │
│ ◀─── postMessage({ type:'progress'})│ 进度上报(可多次)
│ onmessage → 更新 UI │
│ │
│ ◀─── postMessage({ type:'done'}) │ 任务完成
│ onmessage → 展示结果 │
│ workerInstance.terminate() │ Worker 销毁
完整代码
主线程:Index.ets
import { worker, MessageEvents, ErrorEvent } from '@kit.ArkTS'
type WorkerStatus = 'idle' | 'running' | 'done' | 'error'
class LogEntry {
time: string = ''
msg: string = ''
isWorker: boolean = false
}
@Entry
@Component
struct WorkerDemo {
@State status: WorkerStatus = 'idle'
@State logs: LogEntry[] = []
@State result: string = ''
@State elapsed: number = 0
private workerInstance: worker.ThreadWorker | null = null
private startTime: number = 0
private startWorker(): void {
if (this.status === 'running') { return }
this.status = 'running'
this.result = ''
this.startTime = Date.now()
// 创建 Worker,路径相对于 entry/src/main/ets/
this.workerInstance = new worker.ThreadWorker('entry/ets/workers/PrimeWorker.ets')
// 接收 Worker 消息
this.workerInstance.onmessage = (event: MessageEvents) => {
const data = event.data as Record<string, number | string>
const msgType = data['type'] as string
if (msgType === 'progress') {
this.addLog(`Worker:已处理到 ${data['current']}`, true)
} else if (msgType === 'done') {
this.elapsed = Date.now() - this.startTime
this.result = `质数个数: ${data['count']}`
this.status = 'done'
this.addLog(`主线程:收到结果 → ${this.result}(${this.elapsed}ms)`)
// 任务完成后必须 terminate,否则 Worker 进程驻留
this.workerInstance?.terminate()
this.workerInstance = null
}
}
// Worker 错误处理
this.workerInstance.onerror = (event: ErrorEvent) => {
this.status = 'error'
this.addLog(`Worker 错误: ${event.message}`)
this.workerInstance?.terminate()
this.workerInstance = null
}
// 发送任务给 Worker
this.addLog('主线程:发送任务 → limit=300000')
this.workerInstance.postMessage({ limit: 300000 })
}
private stopWorker(): void {
this.workerInstance?.terminate() // 强制终止
this.workerInstance = null
this.status = 'idle'
this.addLog('主线程:已终止 Worker')
}
// ... build() 略,见配套源码
}
Worker 脚本:workers/PrimeWorker.ets
import { worker, MessageEvents } from '@kit.ArkTS'
// workerPort 是 Worker 侧的消息端口
const ctx = worker.workerPort
ctx.onmessage = (event: MessageEvents) => {
const data = event.data as Record<string, number>
const limit = data['limit'] as number
const sieve: boolean[] = new Array<boolean>(limit + 1).fill(true)
sieve[0] = false
if (limit >= 1) { sieve[1] = false }
const step = Math.floor(limit / 5)
for (let i = 2; i * i <= limit; i++) {
if (sieve[i]) {
for (let j = i * i; j <= limit; j += i) {
sieve[j] = false
}
}
// 每 step 步上报一次进度给主线程
if (i % step === 0) {
ctx.postMessage({ type: 'progress', current: i })
}
}
let count = 0
for (let k = 0; k <= limit; k++) {
if (sieve[k]) { count++ }
}
ctx.postMessage({ type: 'done', count: count })
}
模拟器运行效果
初始状态

执行完成(含通信日志)
Worker 执行完成,找到 25997 个质数(300000 以内),耗时 53ms。通信日志清晰展示了「主线程创建→发送任务→收到结果」全链路。

关键知识点
1. Worker 文件路径规则
// ✅ 正确:路径从 entry/ets/ 开始,写相对路径
new worker.ThreadWorker('entry/ets/workers/PrimeWorker.ets')
// ❌ 错误:不能写绝对路径或 ./ 相对路径
new worker.ThreadWorker('./workers/PrimeWorker.ets') // 报错
2. 消息序列化限制
postMessage 传递的数据会被结构化克隆(Structured Clone),支持:
- 基础类型:number、string、boolean
- 普通对象:
Record<string, ...> - 数组:
number[]、string[]
不支持(会抛出错误):
- 函数、Symbol
- DOM/UI 对象
- 带方法的类实例(只传数据,不传行为)
3. 必须显式 terminate
Worker 线程不会自动销毁。忘记调用 terminate() 会导致:
- Worker 进程驻留内存
- 多次创建 Worker 导致内存泄漏
- 影响设备续航(Worker 持续占用 CPU 时间片)
// ✅ 正确的清理模式
this.workerInstance?.terminate()
this.workerInstance = null
4. 双向通信设计模式
用 type 字段区分消息类型(类似枚举的消息协议):
// Worker 侧
ctx.postMessage({ type: 'progress', current: i }) // 进度
ctx.postMessage({ type: 'done', count: count }) // 完成
// 主线程侧
if (msgType === 'progress') { /* 更新进度 UI */ }
else if (msgType === 'done') { /* 展示结果 */ }
常见问题
Q:Worker 能访问 UI 组件吗?
A:不能。Worker 运行在独立 JS 引擎,完全没有 UI 上下文。所有 UI 更新必须在主线程的 onmessage 回调中完成。
Q:Worker 里能用 fetch 发网络请求吗?
A:HarmonyOS 的 Worker 支持使用 @ohos.net.http,但需要在 Worker 侧单独 import。Worker 有完整的运行时环境,可以使用大多数系统 API。
Q:应用退到后台,Worker 还在跑吗?
A:Worker 跟随应用进程生命周期。应用进入后台后,系统可能限制 Worker 的 CPU 时间;应用被杀死,Worker 同时销毁。如需真正后台执行,应使用 BackgroundTaskManager。
更多推荐


所有评论(0)