鸿蒙开发:事件订阅EventHub

程序员一鸣
• 阅读 17

前言

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

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

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

简单案例

@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方法介绍

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

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

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

点赞
收藏
评论区
推荐文章
Flutter 异步编程指南
在App开发中,经常会遇到处理异步任务的场景,如网络请求、读写文件等。Android、iOS使用的是多线程,而在Flutter中为单线程事件循环,如下图所示
JAVA多线程并发编程-避坑指南
本篇旨在基于编码规范、工作中积累的研发经验等,整理在多线程开发的过程中需要注意的部分,比如不考虑线程池参数、线程安全、死锁等问题,将会存在潜在极大的风险。并且对其进行根因分析,避免每天踩一坑,坑坑不一样。
Stella981 Stella981
3年前
Guava — EventBus
Guava提供了事件总线的一个实现方案EventBus。它是事件发布订阅模式的实现,观察者模式。Guava为我们提供了同步实现EventBus和异步实现AsyncEventBus两个事件总线,他们都不是单例的eventBus.post(1);eventBus.post(1L);post方法,直接发布事件订阅者需要注册进来,ev
Stella981 Stella981
3年前
EventBus源码分析
一、        EventBus简介1.1、EventBusEventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化Android事件传递,这里的事件可以理解为消息,本文中统一称为事件。事件传递既可用于Android四大组件间通讯,也可以用户异步线程和主线程间通讯等等。传统的事件
Stella981 Stella981
3年前
Android面试之EventBus
简介众所周知,EventBus是一款用在Android开发中的发布/订阅事件总线框架,基于观察者模式,将事件的接收者和发送者分开,简化了组件之间的通信操作,使用简单、效率高、体积小!EventBus使用了典型的发布/订阅事件模式,下面是EventBus官方给出的原理示意图。!在这里插入图片描述(https://oscimg.o
Stella981 Stella981
3年前
ABP EventBus(事件总线)
事件总线就是订阅/发布模式的一种实现  事件总线就是为了降低耦合1.比如在winform中 到处都是事件 !(https://oscimg.oschina.net/oscnet/ed3426bf15550c4b0623956eb95e826780d.png)触发事件的对象 sender事件的数据  e事件的处理逻辑 方法
Stella981 Stella981
3年前
EventBus 线程切换原理
主要问题其实只有两个,其一:如何判断当前发送事件的线程是否是主线程;其二:如何在接收事件时指定线程并执行;一个一个来看。1.如何判断是否在主线程发送EventBus在初始化的时候会初始化一个MainThreadSupport对象,它会去获取主线程的Looper对象并存起来。(当前最新版本如果不是Android环境MainThread
Stella981 Stella981
3年前
NET Core Web API下事件驱动型架构CQRS架构中聚合与聚合根的实现
NETCoreWebAPI下事件驱动型架构在前面两篇文章中,我详细介绍了基本事件系统的实现,包括事件派发和订阅、通过事件处理器执行上下文来解决对象生命周期问题,以及一个基于RabbitMQ的事件总线的实现。接下来对于事件驱动型架构的讨论,就需要结合一个实际的架构案例来进行分析。在领域驱动设计的讨论范畴,CQRS架构本身就是事件驱动的,因此,我打算首先介
Stella981 Stella981
3年前
Noark入门之异步事件
引入异步事件主要是为了各模块的解耦,每当完成一个动作时,向系统发布一个事件,由关心的模块自己监听处理,可选择同步处理,异步处理,延迟处理。何时发布事件,当其他模块关心此动作时<br比如获得道具时,任务系统模块要判定完成进度,BI模块需要上报等等都可以监听此事件,已达模块解耦0x00事件源一个实现xyz.noark.core.event
Stella981 Stella981
3年前
Noark入门之协议映射
0x00消息控制器消息控制器,主要作用就是为每个模块提供消息处理的入口.这里的消息不仅仅是协议,还有内部指令,事件等等逻辑入口,这也是为了响应线程模型作出的一种支撑,只要入口在此消息控制器内,那必然走期望的线程调度。@Controller用于标识一个类为当前模块的消息控制器入口.@Controller(threadGroup