首页 > 编程笔记 > 通用技能 阅读:4

鸿蒙Emitter通信详解(附带示例)

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 已经能够正确接收事件,并将事件的信息显示在页面上了。

相关文章