Simple Global Event Bus Using Kotlin SharedFlow and Koin for Android
In past, We were using the EventBus library for implementing global event bus in our Android apps. It is still used by many great apps. But if you are starting work on a new Android project using Kotlin, I would recommend using the way given in this post.
Kotlin has brought a lot of new features for making developer life easy. Kotlin coroutines and flow are most helpful in handling states, and background tasks with few lines of code. So we will implement a global event bus using the latest features of Kotlin.
The event bus is helpful for sending events (independent data) across app components such as Activities, Fragments, Services, etc.
What is SharedFlow?
If I explain it in simple words, Whatever value we send in this flow will be shared with each receiver. More technically, We can emit values to every collector of this flow.
SharedFlow is hotFlow that shares emitted values among all its collectors in a broadcast fashion.
Let’s start coding. First, we will create AppEventBus class. It is good practice to add an App prefix to class names that will be used globally in the project.
The AppEventBus class will have a variable of SharedFlow. That variable helps us to emit and collect values passed to SharedFlow. Also, we will add two methods for making EventBus code more readable.
AppEventBus methods
- Subscribe — This function will receive events anywhere in the app code.
- Emit — For sending events to the global event bus.
Look at the above code. Now you are wondering what is AppEvent and where it is implemented.
AppEvent is a sealed class for declaring all global events. For example, It can have two types of events.
- Event with Data — This type of event is used for sending independent data with any event using data class. For example ShowAlert, ChangeLanguage, etc.
- Event without data — This type of event will be used for actions that do not require any data. For example Logout, ShowLoader, etc.
Now it is time to use our AppEventBus globally. For doing that, We will need to create a singleton instance of AppEventBus class. So we will use Koin (Kotlin dependency injection) library for that. I think it provides the best way to create a global singleton instance.
Koin integration steps
1. Add dependency to build.gradle
2. Create AppModule.kt
3. Start Koin in the Application class
Using AppEventBus in Project
AppEventBus can be used almost anywhere in the app code with Koin dependency injection. Here I will demonstrate how to use it for sending events from Fragment and Service to Activity. In most projects, we create single activity and multiple fragments and services.
Subscribe global event bus by injecting the AppEventBus instance in MainActivity or anywhere else. In subscribe method, We have to pass the coroutine scope for collecting all data from internal SharedFlow. Another parameter is a block for handling all events. We have passed lifecycleScope in subscribe method, So it will automatically unsubscribe the flow when the activity gets destroyed.
We have injected AppEventBus and subscribed in MainActivty. Now we will learn about how to send events from Fragment or Service.
Send global events from Fragment
Send global event from Service
For using Flow in any class requires coroutine scope, And that is not available in the Service class. In Activity and Fragment, It has lifecyleScope which is part of the Lifecycle library of android. For the Service class, we will create a coroutine scope using MainScope for launching coroutines inside Service class functions.
Wrap up!
We have learned how Kotlin Flow can be helpful to implement something that can be done without using 3rd party library. Kotlin has a lot of developer-friendly features.
I have used the above techniques in many of my professional projects. If you find it helpful, Then support me with claps. For any questions, comment below.
I will share more proven implementations in the next articles.
Thanks for reading!