Ease communication between Activities, Fragments, Dialogs, Services, AsyncTaks, and Life Cycles of Anything by using event bus in Android.
Event bus is an implementation of publish/subscribe pattern which is a messaging system between a subscriber and a publisher. A subscriber waits for an event to be dispatched from a publisher.
In this article I will describe how to benefit an event bus by using Greenrobot‘s EventBus library.
Table of contents
- What is subscribe and publish pattern
- EventBus in a nutshell
- How to add EventBus to your project
- How to use EventBus in 3 Steps
- Main features of EventBus
- Useful scenarios to use EventBus in your project
- Drawbacks of using EventBus in your project
- Alternatives to EventBus
- Conclusion(TL;DR)
- Example Project
1. What is subscribe and publish pattern
Subscribe and publish pattern is a messaging pattern in which subscribers register for a specific event to be dispatched from a publisher.
The subscriber and publisher don’t have any relation or communication between them. Usually, this relation should be coupled between these parties. However, to be able to send events to the correct responder, there is a middleman, an event bus, in between publisher and subscriber as it is seen on Figure 1.
Publisher posts an event to the bus and then bus delivers this event to the registered subscribers.
2. EventBus in a nutshell
EventBus is an android library which lets you use the subscribe/publish pattern easily.
- It is the most commonly used event bus in android society
- Decouples senders & receivers
- Delivers to or from other threads
- Verly little footprint (50kb)
3. How to add EventBus to your project
EventBus is on the Maven Central repository which means you can just add it to your gradle build file.
compile 'org.greenrobot:eventbus:3.0.0'
4. How to use EventBus in 3 Steps
Define an event(message):
Events are the messages that you want to send from your publisher and then receive it from your subscriber. They are literally POJOs and nothing special.
public class Message{
private final String message;
public Message(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
Register and Unregister for Events
To be able to receive events, the class must register/unregister for event bus. The best place for activities and fragments is onStart()
and onStop()
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
@Subscribe annotation and subscription
To be able to receive an event you have to subscribe to that event. To do that, add @Subscribe annotation to one of your methods in your class.
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(Message event){
mytextview.setText(event.getMessage());
}
Setting threadMode in Subscribe annotation is optional.
Post an event
EventBus.getDefault().post(new Message("hello world"));
5. Main features of EventBus
Deliver events to different threads (Main, Background, Async)
You can post an event from a background task like asynctask or any thread, and then you can receive it in main(ui) thread.
Post sticky events
Normally when your activity is suspended or paused, then your activity will not receive and event. Actually this is the promise of the event bus. However, you would have want to see the result of that long network request when you resume your activity(or recreated activity).
To be able to receive the latest and unconsumed event, you should post as sticky in EventBus like so:
EventBus.getDefault().postSticky(new MessageEvent("Sticky message"));
And, to subscribe a sticky event
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onEvent(SimpleEvent event) {
...
}
Subscriber priorities and event canceling
When there are more than one subscriber(receiver) for an event, it will be convenient to receive the event according to priorities of the registered subscribers.
To be able to set the priority you should register like so:
@Subscribe(priority = 1)
public void onMessage(Message event){
mytextview.setText(event.getMessage());
}
No configuration needed
You can use directly the default instance of event bus EventBus.getDefault()
Annotation based usage
As you can notice from the previous examples, all of the configurations are made in annotations. However, Greenrobot’s EventBus is not using reflection to process this annotations. Mainly beacase in Android, Java reflection is a performance problem and its not recommended.
EventBus uses compile time annotation processing to index the subscribers.
6. Useful scenarios to use EventBus in your project
Fragment & Activity Comminication
One of the main problems in an Android development is to decide and implement the communication between fragments and their host activities.
In dark ages, you could have created an interface and then implement it in your activity. And then when you need to call some methods in your activity from your fragment, you can do that by this unproductive way.
By using an event bus, you just post your event from the fragment and you now the activity will receive it without doing anything else on your part.
Background Service to Fragment and/or Activity Comminication
In an Android service, that can perform long running tasks in the background without any user interface, you could potentially broadcast and intent to your Activity and you could receive and intent by extending IntentService in your Service.
Or you could implement Bound Services, and messengers as described in android developer guides.
Isn’t it easier to just post and event that you want to receive on the other hand without handling that boilerplate implementations? We can use EventBus here to ease the communication between out Services and any other components.
7. Drawbacks of using EventBus in your project
Boilerplate event class generation
You will have events for everything therefore it can be considered redundant to have that much messaging classes.
Code is way too loosely coupled
Whenever your project becomes too complex, you have to find your subscriber in a convenient way like searching in class/project.
Background Services
If you start your background services in a different “process” then there is no way to communicate by using an event bus. Because your activities and your service are not in the same process and cannot interact with each other. However, it is not a common scenario.
In the example project the timer sends events in the background service
private static class SimpleTimerTask extends TimerTask {
private AtomicInteger current;
public SimpleTimerTask(AtomicInteger current) {
this.current = current;
}
@Override
public void run() {
EventBus.getDefault()
.postSticky(new SimpleEvent(current.addAndGet(1)));
}
}
8. Alternatives to EventBus
Square’s Otto
Square’s Otto library is a direct alternative to Greenrobot’s EventBus. However, it is deprecated at version 1.3.8 in favor of RxJava and RxAndroid.
RxBus implemented using RxJava
If you are into reactive programming then you can implement your own event bus by using RxJava. On the other hand there is no library for RxBus, however, its implementation is easy and you could implement the event bus in reactive way on your own. You can find an example implementation RxBus implementation here.
9. Conclusion(TL;DR)
In conclusion, EventBus is a great addition to your android arsenal. It can ease the comminication between activities, fragments, dialogs, services, asynctasks, etc.
I highly recommend using EventBus in your android project. Once you get used to using events in your app -it doesn’t take much time- then you will be more “productive” when you develop your android application. Just be careful about drawback and pitfalls.
10. Example Project
You can check out the example project about the topics which I covered in this post on Github.
In this example project, you can find a background service which is started on button click and it starts a timer which sends events. And the “MainActivity” receives this “SimpleEvent”.
Also activity is talking to the service by using events as well.
The covered topics are;
- register/unregister to “EventBus”
- subscribe to events
- sticky events
- communication between background service & activity & recycler view
Thanks for reading. I would greatly appreciate if you share it.
Leave a Reply