HarmonyOS 鸿蒙Next中事件广播EventHub和Emitter的使用场景与区别具体是什么?
HarmonyOS 鸿蒙Next中事件广播EventHub和Emitter的使用场景与区别具体是什么? 移动应用开发的同学应该比较了解EventHub,类似于EventBus。标准的事件广播通知,订阅,取消订阅的处理。EventHub模块提供了事件中心,提供订阅、取消订阅、触发事件的能力。
类似的框架工具有很多,例如MQTT。使用起来也超级简单,从介绍上就能大体了解使用方式,见名知意的一种快捷工具。通过一个事件ID即TAG作为唯一的key,进行事件广播通知和订阅。
看起来Emitter和EventHub区别不大,请问事件广播EventHub和Emitter的使用场景与区别具体是什么?
一、代码实现和详细解释
EventHub是什么?
在ArkUI框架中,EventHub通过单例对象的形式提供,因为放在上下文里。所以每个UIAbility对应一个EventHub。不同的UIAbility的EventHub是不同步的。
从上下文获取EventHub有两种方式:
- 在UIAbility中直接通过context获取:
import { UIAbility, Context, Want, AbilityConstant } from '@kit.AbilityKit';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 获取eventHub
let eventhub = this.context.eventHub;
});
}
}
- 在page界面或者组件中,通过UIcontext强转为UIAbilityContext获取:
let context = getContext(this) as common.UIAbilityContext;
let eventhub = context.eventHub;
获得到EventHub单例对象后,就可以调用emit发送事件,on监听事件,off取消监听事件。进行事件广播的使用。
// TAG作为事件的id为字符串类型
private EVENT_TAG: string = "TEST";
/**
* EventHub事件回调
*/
callbackByEventHub = (content: string)=>{
promptAction.showToast({
message: JSON.stringify(content)
});
}
this.eventHub?.on(this.EVENT_TAG, this.callbackByEventHub); this.eventHub?.off(this.EVENT_TAG, this.callbackByEventHub);
this.eventHub?.off(this.EVENT_TAG);// 第二个参数不传,则代表EVENT_TAG下的所有注册回调都清空
Emitter是什么?
类似于EventHub的使用,只是内部封装了事件队列和分发的机制。多了事件id和优先级的概念。并且Emitter也可以在不同线程内调用。
Emitter区别于上文中的EventHub的事件ID,定义了一层对象进行约束。除了事件id,还需要设置事件级别。
private event: emitter.InnerEvent = {
eventId: this.eventId,
priority: emitter.EventPriority.LOW // 定义一个eventId为1的事件,事件优先级为Low
};
和EventHub不同的是,事件广播的内容,也进行了约束。 发送事件时传递的数据,支持数据类型包括Array、ArrayBuffer、Boolean、DataView、Date、Error、Map、Number、Object、Primitive(除了symbol)、RegExp、Set、String、TypedArray,数据大小最大为16M。
data是key val形式的对象,可以自己定义里面的key和val。
let eventData: emitter.EventData = {
data: {
content: '测试数据',
id: 1,
isEmpty: false
}
};
事件的广播发送,订阅和取消订阅与EventHub区别不大。只是多了once一次性监听而已。
private callback = (eventData: emitter.EventData): void => {
};
emitter.emit(this.event, eventData);
emitter.once(this.event, this.callback)
emitter.off(this.event.eventId, this.callback);
EventHub和Emitter的使用场景与区别
- EventHub是线程内使用的时间广播工具,Emitter是线程间通信使用的工具
- EventHub的使用更简单,属于轻量级的广播工具,主要用于UIAbility和page之间,page和组件之间,组件和组件之间,UI和VM之间的通信,传递的数据内容形式多变且方便(…args: Object[])。Emitter属于重量级的广播工具,封装了优先级和队列的逻辑。传递的数据内容,必须有包裹成进行约束(emitter.EventData)
- Emitter监听设置,在on基础上,额外提供了once一次性监听的API。触发之后不需要再手动off取消监听。EventHub则没有。
二、DEMO源码示例:
import { emitter } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct EventHubAndEmitterTestPage {
// --------------- EventHub
private context = getContext(this) as common.UIAbilityContext;
private eventHub: common.EventHub | null = null;
private EVENT_TAG: string = "TEST";
private emitByEventHub(){
this.eventHub = this.context.eventHub;
this.eventHub.emit(this.EVENT_TAG, "测试数据EventHub");
}
/**
* EventHub事件回调
*/
callbackByEventHub = (content: string)=>{
promptAction.showToast({
message: JSON.stringify(content)
});
}
private registerByEventHub = ()=>{
this.eventHub?.on(this.EVENT_TAG, this.callbackByEventHub);
}
private unRegisterByEventHub = ()=>{
this.eventHub?.off(this.EVENT_TAG, this.callbackByEventHub);
}
// --------------- Emitter
private eventId: number = 1;
private event: emitter.InnerEvent = {
eventId: this.eventId,
priority: emitter.EventPriority.LOW // 定义一个eventId为1的事件,事件优先级为Low
};
private emitByEmitter(){
let eventData: emitter.EventData = {
data: {
content: '测试数据',
id: 1,
isEmpty: false
}
};
// 发送eventId为1的事件,事件内容为eventData
emitter.emit(this.event, eventData);
}
private callback = (eventData: emitter.EventData): void => {
promptAction.showToast({
message: JSON.stringify(eventData)
});
};
private registerByEmitter(){
emitter.on(this.event, this.callback);
// 监听触发后,自动消除监听。不需要手动off
emitter.once(this.event, this.callback)
}
private unRegisterByEmitter(){
emitter.off(this.event.eventId, this.callback);
}
// ---------------点击事件处理
onEmitEvent = ()=>{
this.emitByEmitter();
this.emitByEventHub();
}
onRegisterEvent = ()=>{
this.registerByEmitter();
this.registerByEventHub();
}
onUnRegisterEvent = ()=>{
this.unRegisterByEmitter();
this.unRegisterByEventHub();
}
/**
* 统一样式封装
*/
@Styles ButtonStyle(){
.width(px2vp(350))
.height(px2vp(200))
.margin({ top: px2vp(66) })
}
build() {
Column(){
Button("发送事件")
.ButtonStyle()
.onClick(this.onEmitEvent)
Button("监听事件")
.ButtonStyle()
.onClick(this.onRegisterEvent)
Button("取消事件")
.ButtonStyle()
.onClick(this.onUnRegisterEvent)
}.size({
width: "100%",
height: "100%"
})
}
}
更多关于HarmonyOS 鸿蒙Next中事件广播EventHub和Emitter的使用场景与区别具体是什么?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
EventHub用于进程内组件通信,基于发布订阅模式,适合UI组件间解耦。Emitter用于跨进程事件通信,基于Common Event Service,支持系统级事件广播。两者核心区别在于通信范围:EventHub限于应用内,Emitter可跨应用。EventHub采用本地总线,Emitter依赖系统服务。
在HarmonyOS Next中,EventHub和Emitter虽然都用于组件间通信,但设计目标和适用场景有明确区别。
EventHub 是应用级的事件中心,主要用于页面间或跨UIAbility的松散耦合通信。其典型场景是:一个页面触发事件,其他一个或多个页面(无论是否活跃)都能接收并处理。它基于事件标识(TAG)的订阅/发布模式,适合全局性、一对多的通知,例如用户登录状态变更后需要同步更新多个页面的用户信息。
Emitter 则是UI组件级的事件发射器,主要用于同一页面内的UI组件之间的通信,特别是父子组件或兄弟组件。它基于事件ID和数据的发送,是ArkUI框架内更轻量、高效的直接通信机制。典型场景是子组件触发事件(如按钮点击)并携带数据,父组件或兄弟组件监听并响应。
核心区别总结:
- 作用域:EventHub是应用全局,Emitter是页面内UI组件间。
- 耦合关系:EventHub实现完全解耦的发布/订阅,Emitter通常在已知组件关系的场景下使用。
- 适用对象:EventHub面向页面或UIAbility,Emitter面向ArkUI组件。
- 性能与资源:Emitter更轻量,适合高频、实时的组件交互;EventHub管理全局订阅,适合低频的跨页面通知。
简单来说,跨页面/跨Ability通信选EventHub,同一页面内UI组件通信选Emitter。

