鸿蒙Emitter通信详解(附带示例)
Emitter 提供了在同一进程不同线程间或同一进程同一线程内,发送和处理事件的能力,包括持续订阅事件、单次订阅事件、取消订阅事件,以及发送事件到事件队列的能力。
使用 Emitter 需要先导入以下模块:
打开 DevEco Studio,选择一个 Empty Ability 工程模板,创建一个名为“ArkTSEmitter”的工程为演示示例。

图 1 界面效果

图 2 订阅事件
单击“发送事件”按钮后界面效果如下图所示:

图 3 发送事件
可以看到,Emitter 已经能够正确接收事件,并将事件的信息显示在页面上了。
使用 Emitter 需要先导入以下模块:
import { emitter } from '@kit.BasicServicesKit';Emitter 主要提供订阅、取消订阅、发送事件 3 项操作。
Emitter主要操作
1) Emitter订阅操作
订阅操作包括以下接口:方法签名 | 功能描述 |
---|---|
on(event: InnerEvent, callback: Callback<EventData>) | 持续订阅指定的事件,并在接收到该事件时,执行对应的回调处理函数。 |
on(eventId: string, callback: Callback<EventData>) | 持续订阅指定事件,并在接收到该事件时,执行对应的回调处理函数。 |
on<T>(eventId: string, callback: Callback<GenericEventData<T>>) | 持续订阅指定事件,并在接收到该事件时,执行对应的回调处理函数(支持泛型数据)。 |
once(event: InnerEvent, callback: Callback<EventData>) | 单次订阅指定的事件,并在接收到该事件并执行完相应的回调函数后,自动取消订阅。 |
once(eventId: string, callback: Callback<EventData>) | 单次订阅指定事件,并在接收到该事件并执行完相应的回调函数后,自动取消订阅。 |
once<T>(eventId: string, callback: Callback<GenericEventData<T>>) | 单次订阅指定事件,并在接收到该事件并执行完相应的回调函数后,自动取消订阅(支持泛型数据)。 |
2) Emitter取消订阅操作
取消订阅操作包括以下接口:方法签名 | 功能描述 |
---|---|
off(eventId: number) | 取消针对该事件 ID 的订阅。 |
off(eventId: string) | 取消订阅指定事件。 |
off(eventId: number, callback: Callback<EventData>) | 取消针对该事件 ID 的订阅;若传入已订阅的 callback,则仅取消该回调,否则不做处理。 |
off(eventId: string, callback: Callback<EventData>) | 取消针对该事件 ID 的订阅;若传入已订阅的 callback,则仅取消该回调,否则不做处理。 |
off<T>(eventId: string, callback: Callback<GenericEventData<T>>) | 取消针对该事件 ID 的订阅;若传入已订阅的泛型 callback,则仅取消该回调,否则不做处理。 |
3) Emitter发送事件
发送事件操作包括以下接口:方法签名 | 功能描述 |
---|---|
emit(event: InnerEvent, data?: EventData) | 发送指定的事件。 |
emit(eventId: string, data?: EventData) | 发送指定的事件。 |
emit<T>(eventId: string, data?: GenericEventData<T>) | 发送指定的事件(支持泛型数据)。 |
emit(eventId: string, options: Options, data?: EventData) | 发送指定优先级事件。 |
emit<T>(eventId: string, options: Options, data?: GenericEventData<T>) | 发送指定优先级事件(支持泛型数据)。 |
Emitter进行线程间通信
接下来演示如何使用 Emitter 来订阅、发送事件。打开 DevEco Studio,选择一个 Empty Ability 工程模板,创建一个名为“ArkTSEmitter”的工程为演示示例。
1) 添加按钮
在 Index.ets 的 Text 组件下,添加 2 个按钮,代码如下:// 订阅事件 Button('订阅事件', { type: ButtonType.Capsule }) .fontSize(40) .fontWeight(FontWeight.Medium) .margin({ top: 10, bottom: 10 }) .onClick(() => { this.subscriberEvent(); }) // 发送事件 Button('发送事件', { type: ButtonType.Capsule }) .fontSize(40) .fontWeight(FontWeight.Medium) .margin({ top: 10, bottom: 10 }) .onClick(() => { this.emitEvent(); })这些按钮都设置了 onClick 单击事件,分别来触发订阅事件和发送事件的操作。界面效果如下图所示:

图 1 界面效果
2) 添加Text组件显示接收的事件
为了能显示接收到的事件的信息,在 2 个按钮下面添加一个 Text 组件,代码如下:// 用于接收事件数据 @State eventData: string = ''; // ... // 接收到的事件数据 Text(this.eventData) .fontSize(50) .fontWeight(FontWeight.Bold)Text 组件的显示内容,通过 @State 绑定了 eventData 变量。当 eventData 变量变化时,Text 的显示内容也会实时更新。
3) 设置按钮的单击事件方法
2 个按钮的单击事件方法如下:// 导入 Emitter import { emitter } from '@kit.BasicServicesKit'; // 定义一个 eventId 为 1 的事件 private event: emitter.InnerEvent = { eventId: 1 }; // ... private subscriberEvent() { // 收到 eventId 为 1 的事件后执行该回调 let callback = (eventData: emitter.EventData): void => { // 接收到事件 this.eventData = "subscribe event success: " + JSON.stringify(eventData); }; // 订阅 eventId 为 1 的事件 emitter.on(this.event, callback); this.message = "subscriber already created"; } private emitEvent() { let eventData: emitter.EventData = { data: { content: 'waylau.com', id: 1, isEmpty: false } }; // 发送 eventId 为 1 的事件,事件内容为 eventData emitter.emit(this.event, eventData); }其中,subscriberEvent() 方法用于订阅事件,emitEvent() 方法用于发送事件。
4) 运行
单击“订阅事件”界面后效果如下图所示:
图 2 订阅事件
单击“发送事件”按钮后界面效果如下图所示:

图 3 发送事件
可以看到,Emitter 已经能够正确接收事件,并将事件的信息显示在页面上了。