前言
线程间通信是并发编程的基础能力,HarmonyOS提供了Emitter机制用于线程间事件传递。@pura/harmony-utils的EmitterUtil封装了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 安装依赖
ohpminstall@pura/harmony-utils2.2 订阅事件
import{EmitterUtil}from'@pura/harmony-utils';privateeventCallback=(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@Componentstruct EmitterDemo{@Stateresult: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';classEventBus{staticreadonlyEVENTS={USER_LOGIN:1001,DATA_REFRESH:2001,NETWORK_CHANGE:3001};staticon(eventId:number,callback:Function):void{EmitterUtil.on(eventId,callback);}staticemit(eventId:number,data?:Object):void{EmitterUtil.emit(eventId,data);}staticoff(eventId:number,callback?:Function):void{EmitterUtil.off(eventId,callback);}}4.2 跨组件通信
EmitterUtil.emit(2001,{action:'refresh',target:'userList'});五、注意事项
- 事件ID:建议使用常量定义事件ID,避免硬编码
- 取消订阅:页面销毁时务必取消订阅,避免内存泄漏
- 回调引用:订阅和取消需使用同一回调引用
- 初始化依赖:使用前需确保
AppUtil.init()已调用 - 事件数据:事件数据应尽量精简,避免传递大对象
六、常见问题
Q1: 事件发送后回调不触发?
检查事件ID是否一致,回调是否正确注册。
Q2: 多次订阅同一事件会触发多次吗?
是的,每个订阅的回调都会触发,注意避免重复订阅。
Q3: 可以跨Ability通信吗?
EmitterUtil支持同进程内的线程间通信,跨进程需使用其他方案。
Q4: 事件数据大小有限制吗?
建议事件数据不超过10KB,大数据建议通过文件或数据库传递。
总结
EmitterUtil的线程间通信方法为组件间和线程间的事件传递提供了便捷支持。本文详细介绍了核心API、使用步骤、完整示例、进阶用法以及常见问题的解决方案。开发者可以利用事件总线模式实现松耦合的组件通信。
本文基于
@pura/harmony-utils工具库,更多功能请参考官方文档与后续系列文章。