英文文档 English Document
FlowBus 是一个基于 Kotlin Coroutines / Flow 的 Flow-first 事件框架。
它主要解决的是“事件广播”问题,不是状态管理框架,也不是对直接函数调用的替代品。
当前仓库包含两个对外模块:
flowbus-core:平台无关的核心模块flowbus(仓库目录library-android):Android 推荐接入模块
如果你经常会遇到这些问题,FlowBus 就会比较顺手:
- 页面 A 想通知页面 B 刷新,但不想直接持有引用
- Fragment 需要通知 Activity 执行某个动作
- ViewModel / Repository / Worker 想异步通知 UI
- 同一个事件需要被多个观察者同时收到
- 你想把事件当成
Flow来订阅、组合、过滤
它更像一个“按类型或命名 channel 分发的广播系统”。
这些场景通常不建议用 FlowBus:
- 页面内部状态管理:优先
StateFlow - 明确的一对一调用:优先直接方法调用 / use case
- 严格请求-响应:优先返回值、挂起函数、专用 channel
- 长期共享状态:优先状态容器,而不是一次性事件
简单理解:
- “一个地方发通知,很多地方可能要响应” -> 可以考虑 FlowBus
- “A 调 B 拿结果” -> 通常不该用 FlowBus
直接从这个依赖开始:
implementation("io.github.logan0817:flowbus:<latest-version>")适合你如果你需要:
- 全局事件广播
- 基于
ViewModelStoreOwner的局部事件作用域 eventFlow<T>()/owner.eventFlow<T>()eventChannel<T>("...")命名事件句柄- 生命周期安全的
collectEvent(...)/onEvent(...)
文档入口:
- 本地文档:
library-android/README.md - GitHub 地址:library-android README
从这个依赖开始:
implementation("io.github.logan0817:flowbus-core:<latest-version>")适合你如果你需要:
- 自己管理
FlowBus实例 - root bus + scoped bus
FlowBusScope生命周期绑定EventKey、eventChannel(...)、sticky event- 非 Android 环境或自己封装上层适配
文档入口:
- 本地文档:
flowbus-core/README.md - GitHub 地址:flowbus-core README
- 主仓库
FlowBus继续维护 Android 模块、Demo 和整体集成。 flowbus-core现在作为 git submodule 挂载在当前目录下,同时拥有自己的独立仓库。- 首次拉取主仓库时请使用
git clone --recurse-submodules ...,或在已有工作区执行git submodule update --init --recursive。
- Android 用户先看
library-android/README.md。 - 先只记住最短路径:发送
postEvent(...),接收onEvent<T> { ... }。 - 如果你需要感知 best-effort 发送是否成功,使用
tryPostEvent(...)/tryPostEventTo(...)。 - 需要限制在某个 Activity / Fragment / NavBackStackEntry 作用域内,再看 owner 版本。
- 同一类型需要多个通道时,再引入
eventChannel<T>("name")。 - 只有当你需要多实例、显式 scope 生命周期或非 Android 使用时,再继续下沉到
flowbus-core。
下面是 Android 最短示例,也是大多数人第一次接入时最有帮助的路径。
data class RefreshHomeEvent(val source: String)postEvent(RefreshHomeEvent(source = "login"))viewLifecycleOwner.onEvent<RefreshHomeEvent> { event ->
viewModel.refreshFrom(event.source)
}这三步就已经够你在项目里开始试用了。
适合:
- 登录成功后多个页面都要刷新
- 后台同步完成后多个观察者都要更新
data class SyncFinishedEvent(val successCount: Int)
postEvent(SyncFinishedEvent(successCount = 3))
viewLifecycleOwner.onEvent<SyncFinishedEvent> { event ->
showResult(event.successCount)
}适合:
- 刷新标题栏
- 请求 Activity 导航
- 当前页面树内部通信,但不想污染全局
data object ReloadToolbarEvent
requireActivity().postEvent(ReloadToolbarEvent)
viewLifecycleOwner.onEvent<ReloadToolbarEvent>(from = requireActivity()) {
renderToolbar()
}适合:
ToastSnackBar- 导航命令
- 同样都是
String,但业务语义不同
val toastChannel = eventChannel<String>("ui.toast")
toastChannel.post("保存成功")
viewLifecycleOwner.onEvent(toastChannel) { message ->
showToast(message)
}适合:
- Repository / Worker / Session 级别隔离
- 需要多个 bus 实例
- 需要 scope 生命周期跟随
CoroutineScope/Job
val syncScope = DefaultFlowBus.openScope("sync-task", closeWhen = scope)
syncScope.post(SyncProgress(percent = 10))
scope.launch {
syncScope.flow<SyncProgress>().collect { progress ->
render(progress)
}
}更详细说明见 flowbus-core/README.md。
| 需求 | 推荐 API |
|---|---|
| 全局发送 | postEvent(...) |
| 想知道 best-effort 是否成功 | tryPostEvent(...) |
| 必须保证写入成功 | emitEvent(...) |
| 发送到某个 owner | postEventTo(owner, ...) / owner.postEvent(...) |
| 命名通道 | eventChannel<T>("name") + channel.post(...) |
| 最短一行监听 | onEvent(...) |
先拿到 Flow 自己组合 |
eventFlow<T>() / owner.eventFlow<T>() |
生命周期安全收集任意 Flow |
collectEvent(flow) { ... } |
| 非 Android / 多实例 / scope 生命周期 | flowbus-core |
post*:非挂起,best-effort,写法最轻tryPost*:非挂起,但会返回当前调用是否已被总线接收emit*:挂起直到成功写入,适合更关键的事件
适合:
- 最新配置
- 最近一次初始化结果
- 后来订阅的人也需要拿到最近一次值
不适合:
- Toast
- 导航
- 一次性点击动作
推荐顺序:
- 单个动作:
data class/data object - 同一业务域多个动作:
sealed interface/sealed class - 只有值真的很简单时,才直接发
String/Int
如果你用 sealed interface 把多个子事件放进同一个通道,发送时记得显式指定父类型:
sealed interface MainUiEvent {
data object Refresh : MainUiEvent
data class ShowToast(val message: String) : MainUiEvent
}
postEvent<MainUiEvent>(MainUiEvent.Refresh)
viewLifecycleOwner.onEvent<MainUiEvent> { event ->
when (event) {
MainUiEvent.Refresh -> refresh()
is MainUiEvent.ShowToast -> showToast(event.message)
}
}- Android 接入与场景说明:
library-android/README.md - Core 能力与多实例 / scope 用法:
flowbus-core/README.md - 英文文档:
README_EN.md
flowbus-core:核心框架模块library-android:Android 适配模块app:demo app
Demo 源码位于 app 模块,可直接运行。建议按这个顺序看:
MainActivity:全局事件、owner 事件、非 UI demo 入口TestFragmentActivity:演示 Activity 作用域事件、eventChannel,以及 Activity / Fragment 在同一 owner 作用域内共享接收LoginActivity:owner 局部总线示例
MIT License
