ease communication between activiities fragments and services

Ease Communication Between Activities, Fragments, and Services

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
  1. What is subscribe and publish pattern
  2. EventBus in a nutshell
  3. How to add EventBus to your project
  4. How to use EventBus in 3 Steps
  5. Main features of EventBus
  6. Useful scenarios to use EventBus in your project
  7. Drawbacks of using EventBus in your project
  8. Alternatives to EventBus
  9. Conclusion(TL;DR)
  10. Example Project
example event bus project screenshot
Example EventBus 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.

EventBus diagram
Figure 1. EventBus diagram to demonstrate subscribe/publish events

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.

  • Majid Arya

    Thanks for your shiny post, this is what exactly i want ,
    I have a one question from you . I implement the tablayout with viewpager in one activity . i have some data in my activity and i want send this data to tablayout fragments , when i use post method it’s not work and when i i use the postSticky method . it’s work
    Thanks for your good blog

    • ViewPager has a offscreen page limit.

      Let’s say you have 5 fragments and you try to send data to the 5th page and the current page is 1.

      So if the offscreen page limit is set to 3 then other pages are destroyed so they cannot listen to the event that you are trying to send.

      That’s why if you send “postSticky” it will be catched by the fragment.

      Maybe you can try to increase the offscreen limit by using “viewPager.setOffscreenPageLimit(10)” so that all of your your pages will remain alive at the same time.

      However, though it will impact the memory usage of your app. Use it wisely.

  • Ersin

    I was looking a solution to send message between activity and service. This article explains everything. Thank you. I thought, i can use intents to communicate because i had doubts on EventBus. Now i can try EventBus.
    ~ Çok makbule geçti 🙂 “

    • EventBus really makes your life easier when you first start the project. And there is no need to send and receive intents. Because eventbus default instance is stayed in the memory as long as the application is active. So it is directly available every class which is subscribed to the events.

      However though, if the project requirements are complex the event bus is a curse rather than a blessing. It is hard to follow your code and hard to unit test.

      Currently my recommended solution is to use Dagger 2 and RxJava. But it takes more time to develop. You could have implemented the same architecture by implementing extra Model layer and inject it to the service and your activity and listen the observables for event emissions. I’m planning to write a new article about these topics as well in near future :).

  • Milan Rawal

    Thankyou alot for detailed explanation on pub/sub pattern and its use.