有没有HarmonyOS鸿蒙Next工程师大佬路过,子线程和主线程如何通讯?

有没有HarmonyOS鸿蒙Next工程师大佬路过,子线程和主线程如何通讯? 大佬们请问子线程和主线程如何通讯?

6 回复

主线程子线程通讯包括有Emitter、Worker、EventHandler和EventRunner等方法。

三大通信方式

  1. Emitter事件总线

    • 方式:子线程订阅 → 主线程触发
    • 场景:实时状态同步(如进度更新)
  2. Worker线程

    • 方式:主线程派任务 → Worker执行 → 回调结果
    • 场景:CPU密集型任务(如图像处理)
  3. EventHandler机制

    • 方式:主线程投递任务 → 子线程队列执行
    • 场景:异步任务调度(如优先级操作)

方案速选指南

需求场景 推荐方案
简单状态通知 Emitter
耗时计算任务 Worker
可控异步调度 EventHandler

核心原则:

  • UI操作仅限主线程
  • 跨线程数据传递需深拷贝
  • 高频通信优选Emitter

更多关于有没有HarmonyOS鸿蒙Next工程师大佬路过,子线程和主线程如何通讯?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


Emitter机制

通过 @ohos.events.emitter 模块实现跨线程事件订阅与发布:

// 主线程监听
emitter.on('updateUI', (data) => {
  this.value = data;
});

// 子线程触发
taskpool.execute(async () => {
  emitter.emit('updateUI', { value: 30 });
}, taskpool.Priority.HIGH);

Worker多线程通信

使用 @ohos.worker 模块通过 postMessage 传递数据:

// 主线程创建Worker
const worker = new worker.ThreadWorker('entry/ets/workers/MyWorker.ts');
worker.onmessage = (event) => { /* 处理数据 */ };

// Worker线程发送数据
workerPort.postMessage({ key: 'value' });

适用于复杂任务场景。

sendablePreferences共享存储

通过持久化存储实现跨线程数据共享:

import { sendablePreferences } from '@kit.ArkData';

// 主线程存储
sendablePreferences.put('key', 'value');

// 子线程读取
taskpool.execute(async () => {
  const value = sendablePreferences.get('key');
});

鸿蒙提供的线程有2种:worker和taskpool

目前通讯主要用emitter:

用法:

在主线程中注册

emitter.on({eventId:1000},
  ()=>
  {
    //...处理业务
  })

在子线程中发送:

emitter.emit({eventId:1000},eventData)

其中eventData是传参,可选

最后记得取消订阅:

emitter.off(1000);

详细内容可以参考指南:使用Emitter进行线程间通信

可以看一下这块文档

ArkTS线程间通信概述-并发线程间通信-ArkTS并发-ArkTS(方舟编程语言)-应用框架 - 华为HarmonyOS开发者

ArkTS目前主要提供两种并发能力支持线程间通信:TaskPool和Worker。

  • Worker是Actor并发模型标准的跨线程通信API,与Web Worker或者Node.js Worker的使用方式基本一致。
  • TaskPool提供了功能更强、并发编程更简易的任务池API。其中TaskPool涉及跨并发实例的对象传递行为与Worker一致,还是采用了标准的Structured Clone算法,并发通信的对象越大,耗时就越长。

在HarmonyOS鸿蒙Next中,子线程与主线程通讯可通过以下方式实现:

  1. 使用EventHub:子线程通过postEvent发送事件,主线程通过subscribeEvent订阅接收
  2. 使用TaskDispatcher:通过GlobalTaskDispatcher获取任务分发器,调用asyncDispatch执行异步任务
  3. 使用Emitter:通过createEmitter创建事件发射器,子线程emit事件,主线程on监听
  4. 使用Worker:通过new Worker创建Worker线程,通过postMessage/onmessage进行通讯

注意跨线程数据需序列化,避免直接共享内存。UI更新必须在主线程执行。

在HarmonyOS Next中,子线程与主线程(UI线程)通信主要有以下几种方式:

  1. TaskDispatcher机制: 使用getUITaskDispatcher()获取UI任务分发器,通过asyncDispatch或syncDispatch方法将任务派发到UI线程执行。

示例代码:

// 在子线程中
let uiTaskDispatcher = taskDispatcher.getUITaskDispatcher();
uiTaskDispatcher.asyncDispatch(() => {
    // 这里更新UI
});
  1. Emitter事件机制: 使用事件发射器进行线程间通信,适合一对多的场景。

示例代码:

// 注册事件
emitter.on("myEvent", (eventData) => {
    // UI线程处理事件
});

// 子线程发射事件
emitter.emit("myEvent", {data: "value"});
  1. Worker线程通信: 对于耗时任务,可以使用Worker线程,通过postMessage和onmessage进行通信。

  2. SharedMemory共享内存: 适合大数据量通信场景,但需要自行处理同步问题。

注意事项:

  • 更新UI必须在UI线程执行
  • 避免在UI线程执行耗时操作
  • 注意线程安全问题

选择哪种方式取决于具体场景,简单UI更新推荐使用TaskDispatcher,复杂通信可以考虑Emitter或Worker。

回到顶部