鸿蒙开发:事件订阅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取消订阅的使用,可以避免内存泄漏,其二就是,关于事件命名的规范,建议使用常量定义事件名,避免硬编码错误。

相关推荐
雨白2 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
幽蓝计划3 小时前
HarmonyOS NEXT仓颉开发语言实战案例:动态广场
华为·harmonyos
kk爱闹3 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空5 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭6 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日6 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安7 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑7 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
万少9 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
幽蓝计划10 小时前
HarmonyOS NEXT仓颉开发语言实战案例:电影App
华为·harmonyos