Ktbus
A simple EventBus implementation based on Kotlin SharedFlow.
Install / Use
/learn @holance/KtbusREADME
Ktbus
A simple EventBus implementation based on Kotlin SharedFlow and inspired by Greenrobot EventBus.
Build
Concept and Usages
Setup
Use MavenCentral in settings.gradle.kts:
repositories {
mavenCentral()
}
Include in application build.gradle.kts:
dependencies {
implementation("org.holance:ktbus:{version}")
}
Make sure to replace {version} with the version of the library.
Publish/Subscribe
flowchart TD
A["Publisher"] --> B(("SharedFlow"))
B --> C["Subscriber 1"] & D["Subscriber 2"]
Example
data class Event1(val value: Int)
data class Event2(val value: Int)
data class Event3(val value: Int)
class SomeClass {
val bus = KtBus.getDefault()
fun setup() {
bus.subscribe(this)
}
fun tearDown() {
bus.unsubscribe(this)
}
@Subscribe
fun onEvent1(event: Event1) {
// Do something with the event
}
@Subscribe(scope = DispatcherTypes.IO)
fun onEvent2(event: Event2) {
// Do something with the event in a IO coroutine scope
}
@Subscribe
fun onEvent3(event: Event3) {
// Do something with the event
}
}
val bus = KtBus.getDefault()
bus.post(Event1(1))
bus.post(Event2(2))
bus.post(Event3(3))
Request/Response
flowchart TD
n1["Request"] --> n2(("SharedFlow"))
n2 --> n3["Subscriber"]
n3 -- Response --> n2
n2 -- Response --> n1
Example
data class ComputeSquareRequest(val value: Int)
data class ComputeSquareResult(val value: Int)
class MathClass {
val bus = KtBus.getDefault()
fun setup() {
bus.subscribe(this)
}
fun tearDown() {
bus.unsubscribe(this)
}
@RequestHandler
fun computeSquare(event: ComputeSquareRequest) : ComputeSquareResult {
return ComputeSquareResult(event.value * event.value)
}
}
val bus = KtBus.getDefault()
try {
val result = bus.request<ComputeSquareRequest, ComputeSquareResult>(ComputeSquareRequest(5))
assert(result.value == 25)
}
catch (e: RequestException) {
// Handle request handler exception
}
catch (e: NoRequestHandlerException) {
// Handle no request handler exception
}
catch (e: RequestTimeoutException) {
// Handle request timeout exception
}
Use Channel
Compile-Time Channel
data class SomeEvent(val value: Int)
class SomeClass {
val bus = KtBus.getDefault()
fun setup() {
bus.subscribe(this)
}
fun tearDown() {
bus.unsubscribe(this)
}
@Subscribe(channel = "channel1")
fun handleEventFromChannel1(event: SomeEvent) {
// Do something with the event
}
@Subscribe(channel = "channel2")
fun handleEventFromChannel2(event: SomeEvent) {
// Do something with the event
}
@Subscribe(channel = "channel3")
fun handleEventFromChannel3(event: SomeEvent) {
// Do something with the event
}
}
val bus = KtBus.getDefault()
bus.post(SomeEvent(1), "channel1")
bus.post(SomeEvent(2), "channel2")
bus.post(SomeEvent(3), "channel3")
Runtime Channel
data class SomeEvent(val value: Int)
class SomeClass(val channel: String) {
class SomeChannelFactory : ChannelFactory {
override fun getChannel(obj: Any): String {
return (obj as? SomeClass)?.channel ?: DefaultChannelFactory.DEFAULT_CHANNEL
}
}
val bus = KtBus.getDefault()
fun setup() {
bus.subscribe(this)
}
fun tearDown() {
bus.unsubscribe(this)
}
@Subscribe(channelFactory = SomeChannelFactory::class)
fun handleEvent(event: SomeEvent) {
// Do something with the event
}
}
val objCh1 = SomeClass("channel1")
objCh1.setup()
val bus = KtBus.getDefault()
bus.post(SomeEvent(1), "channel1")
Related Skills
node-connect
350.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
110.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
350.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
350.8kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
