在HarmonyOS应用开发中,当需要进行组件间或模块间的事件发布与订阅以实现解耦通信时,部分三方库(如EventBus)可能未提供HarmonyOS适配版本。开发者需要寻找系统提供的替代方案来实现基于发布-订阅模式的事件通信机制。
EventHub是HarmonyOS系统提供的基于发布-订阅模式实现的事件通信机制。通过事件名,实现了发送方和订阅方之间的解耦,支持不同业务模块间的高效数据传递和状态同步。更多参考请参见EventHub。
使用系统提供的EventHub替代EventBus。通过UIAbilityContext获取EventHub实例,使用on方法订阅事件,使用emit方法发送事件,并在Ability销毁时调用off方法取消订阅以避免内存泄漏。在ArkUI组件中,可通过getContext(this)获取UIAbilityContext,从而在组件侧使用EventHub进行事件通信。
import { UIAbility } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
export default class EntryAbility extends UIAbility {
value: number = 12;
// 统一错误处理函数
handleEventError(e: BusinessError) {
let code: number = e.code;
let msg: string = e.message;
console.error(`EventHub error, code: ${code}, msg: ${msg}`);
}
onCreate() {
try {
// 支持使用匿名函数订阅事件
this.context.eventHub.on('myEvent', () => {
console.info(`anonymous eventFunc is called, value: ${this.value}`);
});
} catch (e) {
this.handleEventError(e as BusinessError);
}
}
onForeground() {
try {
// 结果:
// anonymouseventFunciscalled, value: 12
this.context.eventHub.emit('myEvent');
} catch (e) {
this.handleEventError(e as BusinessError);
}
}
onDestroy() {
// 销毁时取消事件订阅,避免内存泄漏
try {
this.context.eventHub.off('myEvent');
} catch (e) {
this.handleEventError(e as BusinessError);
}
}
} import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Index {
value: number = 10;
aboutToAppear() {
// 在组件中通过getContext(this)获取UIAbilityContext
let context = getContext(this) as common.UIAbilityContext;
try {
context.eventHub.on('componentEvent', () => {
console.info(`componentEvent is called, value: ${this.value}`);
});
} catch (e) {
let code: number = (e as BusinessError).code;
let msg: string = (e as BusinessError).message;
console.error(`subscribe componentEvent failed, code: ${code}, msg: ${msg}`);
}
}
aboutToDisappear() {
// 组件销毁时取消订阅,避免内存泄漏
let context = getContext(this) as common.UIAbilityContext;
try {
context.eventHub.off('componentEvent');
} catch (e) {
let code: number = (e as BusinessError).code;
let msg: string = (e as BusinessError).message;
console.error(`unsubscribe componentEvent failed, code: ${code}, msg: ${msg}`);
}
}
build() {
Column() {
Button('发送事件')
.onClick(() => {
let context = getContext(this) as common.UIAbilityContext;
try {
context.eventHub.emit('componentEvent');
} catch (e) {
let code: number = (e as BusinessError).code;
let msg: string = (e as BusinessError).message;
console.error(`emit componentEvent failed, code: ${code}, msg: ${msg}`);
}
})
}
}
}