欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

前言

在 Flutter 开发中,状态管理(Provider, Bloc, GetX)解决了大部分组件通信问题。
通过 EventBus,我们可以实现跨组件、跨页面、甚至跨业务模块的离散事件通知(如:退出登录通知、全局主题变更、接收到推送消息)。

event_bus 是 Dart 社区最经典的事件总线库,基于 Stream 实现,简单且高效。

对于 OpenHarmony 开发者,event_bus 是一种极其廉价的解耦手段,特别是当你需要从非 UI 代码(如网络层、插件层)向 UI 层发送通知时。

一、核心原理

EventBus 本质上是一个全局的 StreamController.broadcast

fire(Event)

Listen

Listen

Listen

发布者

EventBus

订阅者 A (页面)

订阅者 B (服务)

订阅者 C (组件)

二、OpenHarmony 适配说明

event_busPure Dart 库,100% 兼容 OpenHarmony

使用禁忌
虽然 EventBus 好用,但不要滥用。不要用它来传递必须被持久化的应用状态(State),否则会让数据流变得难以追踪(Spaghetti Code)。它最适合处理“一次性”的、“广播式”的通知。

三、基础用例

3.1 定义事件

class UserLoggedInEvent {
  final String username;
  UserLoggedInEvent(this.username);
}

class ThemeChangedEvent {
  final bool isDark;
  ThemeChangedEvent(this.isDark);
}

3.2 创建总线与发送事件

通常作为一个全局单例或通过 GetIt 注入。

import 'package:event_bus/event_bus.dart';

// 全局实例
EventBus eventBus = EventBus();

void performLogin() {
  print('登录成功...');
  // 发送事件
  eventBus.fire(UserLoggedInEvent('WangBaolong'));
}

3.3 监听事件

void listenToEvents() {
  // 监听特定类型的事件
  eventBus.on<UserLoggedInEvent>().listen((event) {
    print('收到登录通知: ${event.username}');
  });
  
  // 监听所有事件
  eventBus.on().listen((event) {
    print('总线收到任意事件: $event');
  });
}

在这里插入图片描述

四、完整实战示例:鸿蒙应用全局通知

这个示例演示了如何在鸿蒙应用中,使用 EventBus 实现一个“夜间模式”切换的全局通知机制。

import 'dart:async';
import 'package:event_bus/event_bus.dart';

// 1. 定义事件
class AppThemeEvent {
  final String themeName;
  AppThemeEvent(this.themeName);
}

// 2. 全局总线
EventBus bus = EventBus();

// 3. 模拟设置页面 (发布者)
class SettingsPage {
  void switchTheme(String newTheme) {
    print('🎨 [SettingsPage] 用户切换主题为: $newTheme');
    bus.fire(AppThemeEvent(newTheme));
  }
}

// 4. 模拟主页 (订阅者)
class HomePage {
  StreamSubscription? _sub;

  void initState() {
    print('🏠 [HomePage] 初始化,开始监听主题变更...');
    _sub = bus.on<AppThemeEvent>().listen((event) {
      print('🏠 [HomePage] 收到主题变更: ${event.themeName}. 正在刷新 UI...');
      _updateUI(event.themeName);
    });
  }

  void _updateUI(String theme) {
    // 省略 setState
  }

  void dispose() {
    print('🏠 [HomePage] 销毁,取消监听');
    _sub?.cancel();
  }
}

// 5. 模拟另一个组件 (另一个订阅者)
class ProfileWidget {
  StreamSubscription? _sub;

  ProfileWidget() {
    _sub = bus.on<AppThemeEvent>().listen((event) {
      print('👤 [ProfileWidget] 也收到了主题变更: ${event.themeName}');
    });
  }
  
  void dispose() => _sub?.cancel();
}

void main() async {
  // 初始化组件
  var home = HomePage()..initState();
  var profile = ProfileWidget();
  var settings = SettingsPage();

  // 模拟操作
  await Future.delayed(Duration(seconds: 1));
  settings.switchTheme('Dark Mode');

  await Future.delayed(Duration(seconds: 1));
  settings.switchTheme('Light Mode');

  //清理
  home.dispose();
  profile.dispose();
}

在这里插入图片描述

五、总结

event_bus 在 OpenHarmony 开发中是一个非常实用的润滑剂。
它填补了组件树层级过深时通信困难的空白。

但请记住黄金法则:在组件销毁 (dispose) 时,务必取消 (cancel) 对 EventBus 的监听。否则,会导致内存泄漏,甚至在组件销毁后回调依然执行引发空指针 Crash。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐