前言

线程间通信是并发编程的基础能力,HarmonyOS提供了Emitter机制用于线程间事件传递。@pura/harmony-utilsEmitterUtil 封装了Emitter的订阅和发送方法,简化了线程间通信的实现。本文将从API说明、代码实战、进阶用法、常见问题等多个维度进行全面讲解,帮助开发者快速掌握并应用到实际项目中。

在这里插入图片描述

一、EmitterUtil核心API

EmitterUtil 提供了以下线程间通信方法:

方法 说明 参数 使用场景
on(eventId, callback) 订阅事件 eventId, callback 事件监听
off(eventId, callback) 取消订阅 eventId, callback 释放资源
emit(eventId, data) 发送事件 eventId, data 事件触发

1.1 核心特性

  • 简洁易用:封装复杂API为一行调用,降低使用门槛
  • 类型安全:完整的TypeScript类型定义,编译期即可发现错误
  • 异常处理:内置异常捕获机制,避免运行时崩溃
  • 线程安全:支持跨线程事件传递

1.2 事件ID管理建议

范围 说明 示例
1000-1999 用户交互事件 点击、长按
2000-2999 数据更新事件 数据刷新、同步
3000-3999 系统状态事件 网络变化、电量变化

二、完整使用步骤

2.1 安装依赖

ohpm install @pura/harmony-utils

2.2 订阅事件

import { EmitterUtil } from '@pura/harmony-utils';

private eventCallback = (data) => {
  this.result = `收到事件: ${JSON.stringify(data)}`;
};

aboutToAppear() {
  EmitterUtil.on(1001, this.eventCallback);
}

aboutToDisappear() {
  EmitterUtil.off(1001, this.eventCallback);
}

2.3 发送事件

Button('发送事件')
  .width('100%')
  .onClick(() => {
    try {
      EmitterUtil.emit(1001, { message: 'Hello from Emitter!' });
      this.result = '事件已发送 📡';
    } catch (e) {
      this.result = '异常: ' + e;
    }
  })

在这里插入图片描述

三、完整页面示例

import { EmitterUtil } from '@pura/harmony-utils';

@Entry
@Component
struct EmitterDemo {
  @State result: string = '';

  aboutToAppear() {
    EmitterUtil.on(1001, (data) => {
      this.result = `收到: ${JSON.stringify(data)}`;
    });
  }

  aboutToDisappear() {
    EmitterUtil.off(1001);
  }

  build() {
    Column({ space: 12 }) {
      Button('发送事件').width('100%').onClick(() => {
        EmitterUtil.emit(1001, { msg: 'Hello' });
      });
      Text(this.result).fontSize(14).fontColor('#333333')
    }
    .padding(16)
  }
}

四、进阶用法

4.1 事件总线

import { EmitterUtil } from '@pura/harmony-utils';

class EventBus {
  static readonly EVENTS = {
    USER_LOGIN: 1001,
    DATA_REFRESH: 2001,
    NETWORK_CHANGE: 3001
  };

  static on(eventId: number, callback: Function): void {
    EmitterUtil.on(eventId, callback);
  }

  static emit(eventId: number, data?: Object): void {
    EmitterUtil.emit(eventId, data);
  }

  static off(eventId: number, callback?: Function): void {
    EmitterUtil.off(eventId, callback);
  }
}

4.2 跨组件通信

EmitterUtil.emit(2001, { action: 'refresh', target: 'userList' });

五、注意事项

  1. 事件ID:建议使用常量定义事件ID,避免硬编码
  2. 取消订阅:页面销毁时务必取消订阅,避免内存泄漏
  3. 回调引用:订阅和取消需使用同一回调引用
  4. 初始化依赖:使用前需确保 AppUtil.init() 已调用
  5. 事件数据:事件数据应尽量精简,避免传递大对象

六、常见问题

Q1: 事件发送后回调不触发?

检查事件ID是否一致,回调是否正确注册。

Q2: 多次订阅同一事件会触发多次吗?

是的,每个订阅的回调都会触发,注意避免重复订阅。

Q3: 可以跨Ability通信吗?

EmitterUtil支持同进程内的线程间通信,跨进程需使用其他方案。

Q4: 事件数据大小有限制吗?

建议事件数据不超过10KB,大数据建议通过文件或数据库传递。

在这里插入图片描述
在这里插入图片描述

总结

EmitterUtil 的线程间通信方法为组件间和线程间的事件传递提供了便捷支持。本文详细介绍了核心API、使用步骤、完整示例、进阶用法以及常见问题的解决方案。开发者可以利用事件总线模式实现松耦合的组件通信。

本文基于 @pura/harmony-utils 工具库,更多功能请参考官方文档与后续系列文章。

Logo

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

更多推荐