鸿蒙开发:事件订阅EventHub

前言

有这样一个案例,页面A跳转到了页面B,页面B又跳转了页面C,在页面C中需要把数据回调至页面A,我们该如何去做?又或者,在一个模块中需要调用另一个模块中的方法,又该如何调用?在很多的场景下,我们都会想到回调的方式,如果层级较多呢?逐级回调能够解决,但是是十分的麻烦,为了解决这个问题,在鸿蒙当中提供了一个类似于EventBus的能力,它就是EventHub。

一句话解读:EventHub是鸿蒙开发中用于线程内通信的事件中心模块,提供了订阅、触发和取消订阅事件的能力。

主要的特点有三个,第一个就是事件中心,基于发布订阅模式,允许通过事件名进行通信,第二个就是仅支持同一线程内的事件传递,不适用于跨进程或虚拟机间的通信,第三个是单例模式,每个AbilityContext实例拥有独立的EventHub,事件操作仅作用于当前上下文

简单案例

TypeScript 复制代码
@Entry
@Component
struct DemoPage {
  aboutToAppear(): void {
    getContext().eventHub.on("test", (data: string) => {
      //订阅指定事件
      console.log("====" + data)
    })
  }

  build() {
    Column() {
      Button("点击")
        .onClick(() => {
          //触发指定事件
          getContext().eventHub.emit("test", "hello")
        })
    }
  }
}

以上的代码,点击按钮之后,就是触发一个test事件,并发送一个hello字符串,在aboutToAppear声明周期中,订阅了test事件,就会接收到发送的消息。

EventHub方法介绍

查看源码,EventHub中共有三个方法,分别是on,off和emit方法,源码如下:

TypeScript 复制代码
on(event: string, callback: Function): void;
   
off(event: string, callback?: Function): void;
   
emit(event: string, ...args: Object[]): void;

on方法

主要用于订阅指定事件。

参数名 类型 必填 说明
event string 事件名称。
callback Function 事件回调,事件触发后调用。

off方法

主要用于取消订阅指定事件,如果传入callback,代表着取消指定的callback对指定事件的订阅,当该事件触发后,将不会回调该callback;如果不传callback,代表着取消所有callback对指定事件的订阅。

参数名 类型 必填 说明
event string 事件名称。
callback Function 事件回调。如果不传callback,则取消订阅该事件下所有callback。

emit方法

用于触发指定事件。

参数名 类型 必填 说明
event string 事件名称。
...args Object[] 可变参数,事件触发时,传递给回调函数的参数。

组件之间数据传递

本身EventHub就三个方法,使用起来也是非常的简单,可以适用于页面或者组件之间的数据传递,或者状态回传,下面就简单的以组件之间的数据传递为案例,简单的演示一下。

TypeScript 复制代码
@Entry
@Component
struct DemoPage {
  @State message: string = ""

  aboutToAppear(): void {
    getContext().eventHub.on("callBack", (data: string) => {
      //订阅事件,接收消息
      this.message = data
    })
  }

  aboutToDisappear(): void {
    //取消订阅
    getContext().eventHub.off("callBack")
  }

  build() {
    Column() {
      Text(this.message)
      TestView()
    }.width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

@Component
struct TestView {
  @State num: number = 0

  build() {
    Button("传递数据")
      .onClick(() => {
        this.num++
        getContext().eventHub.emit("callBack", "传递一个数据:" + this.num)
      })
  }
}

如果你只是想发送一个通知,可以不带参数。

相关总结

EventHub主要提供了轻量级的线程内通信机制,适用于组件间数据同步、状态通知等场景,在实际的开发中,一定要注意两个事项,其一就是,注意off取消订阅的使用,可以避免内存泄漏,其二就是,关于事件命名的规范,建议使用常量定义事件名,避免硬编码错误。

相关推荐
xiangpanf10 分钟前
Laravel 10.x重磅升级:五大核心特性解析
android
robotx3 小时前
安卓线程相关
android
RickeyBoy3 小时前
独立 App 配置阿里云 CDN 记录
ios
消失的旧时光-19433 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon4 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon5 小时前
VSYNC 信号完整流程2
android
dalancon5 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
不爱吃糖的程序媛5 小时前
OpenHarmony 工程结构剖析
harmonyos
白玉cfc6 小时前
接口与API设计
ios·objective-c
用户69371750013846 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能