目录
[1.1 TaskPool 基础用法:加法计算](#1.1 TaskPool 基础用法:加法计算)
[1.2 TaskPool 网络请求:并发 HTTP 调用](#1.2 TaskPool 网络请求:并发 HTTP 调用)
[1.3 TaskPool 跨线程通信:sendData/onReceiveData](#1.3 TaskPool 跨线程通信:sendData/onReceiveData)
[2.1 Worker 基础通信:Hello World](#2.1 Worker 基础通信:Hello World)
[2.2 Worker 计算任务:倍数计算](#2.2 Worker 计算任务:倍数计算)
[2.3 Worker 与 UI 状态同步:AppStorage](#2.3 Worker 与 UI 状态同步:AppStorage)
在鸿蒙应用开发中,UI 线程负责渲染界面和响应用户交互,若在 UI 线程中执行耗时操作 (如网络请求、复杂计算),会导致界面卡顿甚至 ANR(应用无响应)。因此,鸿蒙提供了TaskPool 和Worker两种多线程方案,用于将耗时任务转移到后台线程执行,保证 UI 流畅。本篇博客将结合实战代码,深度解析这两种多线程机制的核心原理、使用场景与相关实践。
1.TaskPool:轻量级并发任务处理
TaskPool 是鸿蒙推荐的轻量级多线程方案,通过**@Concurrent装饰器**标记并发函数,由系统自动调度线程池执行任务,无需手动管理线程生命周期。
1.1 TaskPool 基础用法:加法计算
代码示例:
TypeScript
import { taskpool } from "@kit.ArkTS"
@Concurrent // 标记为并发函数,可被TaskPool调度
function add(num1: number, num2: number): number {
return num1 + num2
}
async function execTask(num1:number,num2: number): Promise<number> {
// 创建Task对象,绑定并发函数与参数
let task: taskpool.Task = new taskpool.Task(add, num1, num2)
// 执行任务,默认返回Promise<Object>,需用as做类型断言
let result = await taskpool.execute(task) as number
console.log("结果为:" + result)
return result
}
@Entry
@Component
struct Demo1 {
@State value1: string = ""
@State num1: number = 0
@State num2: number = 0
build() {
Column({ space: 20 }) {
Text("计算的结果为:" + this.value1)
TextInput({placeholder:"1.请输入一个数:"}).onChange((value)=>{
this.num1 = Number(value)
})
TextInput({placeholder:"2.请输入一个数:"}).onChange((value)=>{
this.num2 = Number(value)
})
// Button("点击开始线程[taskpool]").onClick(() => {
//
// let resultObject = execTask(this.num1,this.num2)
//
// resultObject.then((value) => {
//
// this.value1 = value + "" // Object -> string
//
// })
// })
Button("点击开始线程[taskpool]").onClick(async() => {
this.value1 = (await execTask(this.num1,this.num2)).toString()
})
// Button("点击开始线程[taskpool]").onClick(() => {
//
// execTask(this.num1,this.num2).then((value) => {
// this.value1 = value.toString() // Object -> string
// })
//
// })
}.width("100%").height("100%").justifyContent(FlexAlign.Center)
}
}
代码解析:
@Concurrent装饰器 :标记add为并发函数,使其可被 TaskPool 识别并调度。- Task 对象创建 :通过
new taskpool.Task(add, num1, num2)绑定函数与参数。 - 类型断言 :
taskpool.execute默认返回Promise<Object>,需用as number将结果转为具体类型。 - 异步更新 UI :通过
await等待任务完成,将结果同步到 UI 线程更新界面。
运行结果:

1.2 TaskPool 网络请求:并发 HTTP 调用
代码示例:
TypeScript
import { taskpool } from "@kit.ArkTS"
import { http } from "@kit.NetworkKit"
@Concurrent
async function httpFunc(url: string): Promise<string> {
let result: string = await new Promise((success: Function, fail: Function) => {
//构建http对象
let httpRequest = http.createHttp()
httpRequest.request(url,
(error, datas) => {
if (!error) {
let resultStr = datas.result
console.log("得到的数据为:" + resultStr)
success(resultStr)
} else {
fail(new Error("处理结果出现问题"))
}
// error ? fail(new Error("请求失败")) : success(datas.result)
})
})
console.log("处理异步消息后after:" + result)
return result
}
async function execTaskPool(url: string): Promise<string> {
let resultMsg = await taskpool.execute(httpFunc, url) as string // 用 `as string` 做类型断言,把 Object 强制转为 string
return resultMsg
}
@Entry
@Component
struct Chapter2 {
@State message: string = '';
build() {
Column() {
Text(this.message).fontSize(18)
Button("发起网络请求[TaskPool]").onClick(() => {
// httpResult是Promise<string>类型
let httpResult =
execTaskPool("http://apis.juhe.cn/idioms/query?key=89deff9ec40d86716ba71b57df74768a&wd=专心致志")
httpResult.then((value) => {
// this.message = value
this.message = JSON.parse(value)?.result?.jbsy?.[0]
})
})
// Button("发起网络请求[TaskPool]").onClick(async() => {
//
// let result = await execTaskPool("")
// this.message = JSON.parse(value)?.result?.jbsy?.[0]
//
// })
}.width("100%").height("100%").justifyContent(FlexAlign.Center)
}
}
代码解析:
- 并发网络请求 :将 HTTP 请求封装为
@Concurrent函数,避免阻塞 UI 线程。 - Promise 封装:用 Promise 包裹 http 请求,统一处理成功 / 失败回调。
- 结果解析 :通过
as string断言结果类型,解析 JSON 后更新 UI。
运行结果:

1.3 TaskPool 跨线程通信:sendData/onReceiveData
代码示例:
TypeScript
import { taskpool } from "@kit.ArkTS"
@Concurrent
async function execSendTask() {
let result1: string = await new Promise((success: Function, fail: Function) => {
setTimeout(() => {
success("执行成功的消息")
}, 3000)
})
console.log("1.处理异步消息后after:" + result1)
taskpool.Task.sendData(result1) // 向UI线程发送数据
console.log("2.task end:")
}
async function taskPoolExec(): Promise<string> {
let task: taskpool.Task = new taskpool.Task(execSendTask)
taskpool.execute(task)
// 接收TaskPool线程发送的数据
let r1 : string = await new Promise((success:Function)=>{
task.onReceiveData((str: string) => {
console.log("接受的数据为:" + str)
success(str)
})
})
return r1
}
@Entry
@Component
struct Chapter4 {
@State str: string = "1111"
build() {
Column() {
Text(this.str)
Button("点击请求").onClick(async () => {
this.str = await taskPoolExec()
})
}.width("100%").height("100%").justifyContent(FlexAlign.Center)
}
}
代码解析:
- 线程间通信 :通过
taskpool.Task.sendData在并发函数中发送数据,task.onReceiveData在 UI 线程接收数据。 - 异步等待结果:用 Promise 封装接收逻辑,确保 UI 线程能获取到后台线程的执行结果。
运行结果:

2.Worker:重量级独立线程
Worker 适用于需要长期运行的后台任务(如 WebSocket 长连接、持续数据处理),拥有独立的执行上下文,需手动管理线程生命周期。
2.1 Worker 基础通信:Hello World
Step 1:配置 Worker 文件路径(build-profile.json5)


Step 2:Worker 线程代码(worker.ets)
TypeScript
import { worker } from "@kit.ArkTS"
//创建worker线程对象
let wk = worker.workerPort
// 接收UI线程消息
wk.onmessage = (e) => {
let str = e.data as string
console.log("worker线程接受UI传递的消息为:" + str)
// 向UI线程返回结果
setTimeout(() => {
wk.postMessage("Worker返回:Hello UI!")
}, 3000)
}
Step 3:UI 线程调用 Worker
TypeScript
import { worker } from "@kit.ArkTS"
@Entry
@Component
struct Chapter5 {
@State msg: string = ""
build() {
Column() {
Text(this.msg).fontSize(20)
Button("启动Worker线程").onClick(() => {
// 在UI的视图中创建worker线程,指定线程文件路径
let worker1 = new worker.ThreadWorker("entry/ets/workers/worker.ets")
// 发送消息到Worker
worker1.postMessage("Hello Worker!")
// 接收Worker返回的消息
worker1.onmessage = (e) => {
let str = e.data as string
console.log("UI视图接受到的线程传递消息为:" + str)
this.msg = str
}
})
}.width("100%").height("100%").justifyContent(FlexAlign.Center)
}
}
代码解析:
- 配置 Worker 路径 :若选择手动创建,必须在
build-profile.json5中注册 Worker 文件,否则系统无法识别。 - 线程双向通信 :通过
postMessage发送消息,onmessage接收消息,实现 UI 与 Worker 的双向通信。 - 独立执行上下文:Worker 拥有独立的内存空间,不能直接访问 UI 线程的变量,需通过消息传递数据。
运行结果:

2.2 Worker 计算任务:倍数计算
Worker 线程代码(workerone.ets)
TypeScript
import { worker } from "@kit.ArkTS"
// 创建worker线程对象
let wk1 = worker.workerPort
wk1.onmessage = (datas) => {
let value = datas.data as string
console.log("接受的数据为:" + value)
setTimeout(() => {
let result1 = Number(value) * 2
console.log("result1:" + result1)
//发送字符串类型
wk1.postMessage("子线程计算的结果为:" + result1)
//wk1.postMessage(result1)
}, 3000)
}
UI 线程调用
TypeScript
import { worker } from "@kit.ArkTS"
@Entry
@Component
struct Chapter6 {
@State num1: string = ""
@State result1: string = "结果为:"
build() {
Column({ space: 20 }) {
Text(this.result1).fontSize(30).fontColor(Color.Black)
TextInput({ placeholder: "请输入一个数:" }).onChange((value) => {
this.num1 = value
console.log("输入的数的值为:" + this.num1)
})
Button("计算2倍结果[Worker]").onClick(() => {
// 创建worker线程对象
let wk2 = new worker.ThreadWorker("entry/ets/workers/workerone.ets")
wk2.postMessage(this.num1)
wk2.onmessage = (e) => {
let r = e.data as string
console.log("接受UI:" + r)
this.result1 = r
}
})
}.width("100%").height("100%").justifyContent(FlexAlign.Center)
}
}
运行结果:

2.3 Worker 与 UI 状态同步:AppStorage
当需要在 Worker 中更新全局状态时,可通过AppStorage实现跨线程状态同步:
UI 线程
TypeScript
import { worker } from "@kit.ArkTS"
// let wrk = AppStorage.link<string>("wrk")
@Entry
@Component
struct Chapter7 {
@State num1: string = ""
@State result1: string | undefined = "结果为:"
@StorageLink("wrk") @Watch("changeResult") wrk: string = ""
changeResult() {
console.log("wrk的变化")
this.result1 = AppStorage.get<string>("wrk")
}
build() {
Column({ space: 20 }) {
Text(this.result1).fontSize(30).fontColor(Color.Black)
TextInput({ placeholder: "请输入一个数:" }).onChange((value) => {
this.num1 = value
console.log("输入的数的值为:" + this.num1)
})
Button("计算并同步状态").onClick(() => {
let wk2 = new worker.ThreadWorker("entry/ets/workers/workerone.ets")
wk2.postMessage(this.num1)
wk2.onmessage = (e) => {
let r = e.data as string
console.log("接受UI:" + r)
AppStorage.set<string>("wrk", r)
}
})
}.width("100%").height("100%").justifyContent(FlexAlign.Center)
}
}
代码解析:
@StorageLink装饰器 :绑定 UI 组件与AppStorage中的状态,状态变化时自动更新 UI。- 跨线程状态同步 :Worker 通过
postMessage发送结果,UI 线程将结果存入AppStorage,触发全局状态更新。
运行结果:

3.总结与比较
鸿蒙的多线程机制为开发者提供了灵活的后台任务处理能力,TaskPool 适合轻量级并发任务,Worker 适合重量级长期任务。在实际开发中,需根据任务特性选择合适的方案,并结合 Promise、类型断言、状态同步等技术,确保多线程代码的健壮性与可维护性。
| 特性 | TaskPool | Worker |
|---|---|---|
| 定位 | 轻量级并发任务池 | 独立的重量级线程 |
| 适用场景 | CPU 密集型、短周期、高并发任务 | IO 密集型、长周期、持续运行任务 |
| 线程管理 | 系统自动调度与复用线程 | 开发者手动创建与管理线程 |
| 通信方式 | 基于 Promise 回调、sendData/onReceiveData | 基于 postMessage/onmessage 双向通信 |
| 配置依赖 | API 11+ 无需配置 | 可选择在build-profile.json5中配置 Worker 文件路径 |