Android EventBus Library Tutorial With Example




Imagine an app that has several activities and fragments in which each component communicates to a single or various components based on some actions. To manage and organise communications between components in such large application is very tedious work. By using EventBus library, such communications can be managed very easily.
EventBus is an open-source library for Android using the publisher/subscriber pattern for loose coupling. It enables central communication to decouple classes with just few lines of simplified code. You can easily pass messages from one class to another with few lines of code without any dependencies between classes. Thus, it speeds up application and make application easily debuggable.

tutorialwing Android EventBus library tutorial

Output

tutorialwing android eventbus library tutorial output

Video Output

Source Code

1. Getting Started

In this tutorial, we will learn how to use this library to communicate between different components(between Fragment and Activity , or between Activity and Activity). Finally, we will get output as shown above.

At first, we will do some basic setup. Then, we will see how a message is broadcasted and received by desired component.

1.1 Creating new project

Follow steps written below to create a new project.
a. Goto File –> New –> New Project. Then, Write application name as EventBusLibraryTutorial and click next.
b. Select Minimum SDK 15 or more –> click next –> Select Empty Activity –> click next –> click finish.
If you have followed above process correctly, you will get a newly created project successfully.

1.2.1 app/build.dradle

Add gradle compile ‘org.greenrobot:eventbus:3.0.0’ in app/build.gradle. Then, click on Sync Now button(Will be shown just after you copy/paste this code into app/build.gradle).

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'

    compile 'org.greenrobot:eventbus:3.0.0'
}

OR

1.2.2 Maven

If you want to use Maven instead of gradle, you can write code as below. However, In this tutorial gradle is being used.

<dependency>
    <groupId>org.greenrobot</groupId>
    <artifactId>eventbus</artifactId>
    <version>3.0.0</version>
</dependency>

1.3 Update Values Folder

At the end of this tutorial, values folders would be like below. You need to add these codes in respective values folder so that you do not get errors while going through this tutorial.
dimens.xml

<resources>
    <dimen name="margin_extra_large">20dp</dimen>
    <dimen name="margin_large">10dp</dimen>
    <dimen name="margin_medium">5dp</dimen>
    <dimen name="padding_large">10dp</dimen>
    <dimen name="padding_medium">5dp</dimen>
</resources>

strings.xml

<resources>
    <string name="app_name">EventBusLibraryTutorial</string>
    <string name="message_received">Message Received:</string>
    <string name="message_main_activity">Message received in MainActivity : </string>
    <string name="message_second_activity">Message received in SecondActivity : </string>
    <string name="message_fragment">Message received in Fragment : </string>
    <string name="title_main">MainActivity</string>
    <string name="title_fragment">Fragment</string>
    <string name="title_stickyEvent">StickyEvent Example</string>
    <string name="hint_message">Enter message</string>
    <string name="send_message_fragment">Send message to Fragment</string>
    <string name="send_message_activity">Send message to Activity</string>
    <string name="show_second_activity">Show Second Activity</string>
</resources>

colors.xml and styles.xml are not changed. So, it is same as created by default.

1.4 Creating Events class

We need to create event which is broadcasted when needed. so, create Events class to be used for communication between components as below. Create an Events.java file in tutorialwing.com.eventbuslibrarytutorial package.
Events.java

package tutorialwing.com.eventbuslibrarytutorial;

public class Events {

	// Event used to send message from fragment to activity.
	public static class FragmentActivityMessage {
		private String message;
		public FragmentActivityMessage(String message) {
			this.message = message;
		}
		public String getMessage() {
			return message;
		}
	}

	// Event used to send message from activity to fragment.
	public static class ActivityFragmentMessage {
		private String message;
		public ActivityFragmentMessage(String message) {
			this.message = message;
		}
		public String getMessage() {
			return message;
		}
	}

	// Event used to send message from activity to activity.
	public static class ActivityActivityMessage {
		private String message;
		public ActivityActivityMessage(String message) {
			this.message = message;
		}
		public String getMessage() {
			return message;
		}
	}
}

Note that Event’s name itself describes who is broadcasting the event and who is receiving the event. For example, Event FragmentActivityMessage means it is being broadcasted by a fragment(i.e. UserFragment) and being received by the activity(i.e. MainActivity). Take another example, ActivityActivityFragment means it is being broadcasted by an Activity(i.e. MainActivity) and being received by an activity(i.e SecondActivity). However, you may choose an event name of your choice. We have chosen this name for the sake of simplicity of this post.

1.5 Creating Global EventBus class

Create a GlobalBus class which returns an instance of EventBus throughout application as below.
GlobalBus.java

package tutorialwing.com.eventbuslibrarytutorial;

import org.greenrobot.eventbus.EventBus;

public class GlobalBus {
	private static EventBus sBus;
	public static EventBus getBus() {
		if (sBus == null)
			sBus = EventBus.getDefault();
		return sBus;
	}
}

Now, we have completed basic setup. so, we will show communications between following components in this tutorial.
1. Communication between Fragment and Activity: Send message from Fragment to Activity and vice-versa.
2. Communication between Activity and Activity: Send message from Activity to Activity.

To register, unregister, broadcast an event or receive an event you need to write code as below.

Register : GlobalBus.getBus().register(this);
Un-Register : GlobalBus.getBus().unregister(this);
Broadcast an event : GlobalBus.getBus().post(eventName);
Receive an event : you need to write a method with annotation @Subscribe as below.

@Subscribe
public void getMessage(Events.EventName event) {
}



2. Communication between Fragment and Activity using EventBus

Here, we will see how a fragment and activity communicates using EventBus library. We will see how any event is broadcasted, how any class is registered to the EventBus, how any broadcasted event is received. We will see real beauty of this library now i.e. how components communicates without being dependent on each other.

We are performing 2 operations:
a. Broadcasting an event to the EventBus.
b. Receiving a broadcasted event.
To broadcast an event, you need to make an instance of event we want to broadcast. Then, post this message to the eventBus. That’s it. You have successfully broadcasted event.
To Receive a broadcasted event, You first need to register to the EventBus. Then, you need to subscribe to the Event using @Subscribe annotation.

2.1 Write code in Fragment to send and receive message

Create a fragment(named UserFragment) and layout(named fragment_user.xml) for it. Then, write code to broadcast an event with some message. Also, write code to receive a broadcasted event.
fragment_user.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:padding="@dimen/padding_medium">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/margin_medium"
        android:text="@string/title_fragment"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title"/>

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/message"
        android:hint="@string/hint_message"/>

    <Button
        android:id="@+id/submit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText"
        android:layout_centerHorizontal="true"
        android:text="@string/send_message_activity"/>

</RelativeLayout>

UserFragment.java

package tutorialwing.com.eventbuslibrarytutorial;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import org.greenrobot.eventbus.Subscribe;

public class UserFragment extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		// Register the event to subscribe.
                GlobalBus.getBus().register(this);
		return inflater.inflate(R.layout.fragment_user, container, false);
	}

	@Subscribe
	public void getMessage(Events.ActivityFragmentMessage activityFragmentMessage) {
		//Write code to perform action after event is received.
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();
                // Unregister the registered event.
		GlobalBus.getBus().unregister(this);
	}
}

Note that @Subscribe is written to subscribes the event( i.e. Events.ActivityFragmentMessage). Also, you should register/unregister the event in onCreateView/onDestroyView method. Finally, our UserFragment.java would be like below.

package tutorialwing.com.eventbuslibrarytutorial;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.eventbus.Subscribe;

public class UserFragment extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                // register the event to listen.
		GlobalBus.getBus().register(this);
		return inflater.inflate(R.layout.fragment_user, container, false);
	}

	@Override
	public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
		super.onViewCreated(view, savedInstanceState);
		setClickListener(view);
	}

	public void setClickListener(final View view) {
		Button btnSubmit = (Button) view.findViewById(R.id.submit);
		btnSubmit.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				EditText etMessage = (EditText) view.findViewById(R.id.editText);

                                // We are broadcasting the message here to listen to the subscriber.
				Events.FragmentActivityMessage fragmentActivityMessageEvent =
						new Events.FragmentActivityMessage(    
                                                String.valueOf(etMessage.getText()));
				GlobalBus.getBus().post(fragmentActivityMessageEvent);
			}
		});
	}

	@Subscribe
	public void getMessage(Events.ActivityFragmentMessage activityFragmentMessage) {
		TextView messageView = (TextView) getView().findViewById(R.id.message);
		messageView.setText(
			getString(R.string.message_received) +
			" " + activityFragmentMessage.getMessage());

		Toast.makeText(getActivity(),
				getString(R.string.message_fragment) +
				" " + activityFragmentMessage.getMessage(),
				Toast.LENGTH_SHORT).show();
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();
                // unregister the registered event.
		GlobalBus.getBus().unregister(this);
	}
}

UserFragment receive a broadcasted event (Events.ActivityFragmentMessage) and broadcast an event (Events.FragmentActivityMessage).

2.2 Write code in Activity to send and receive message

Similarly, we will receive a broadcasted event(Events.FragmentActivityMessage) and broadcast an event(i.e. Events.ActivityFragmentMessage) in MainActivity. Final code in MainActivity.java

package tutorialwing.com.eventbuslibrarytutorial;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.eventbus.Subscribe;

public class MainActivity extends AppCompatActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		addFragment();
	}

	@Override
	protected void onStart() {
		super.onStart();
		// Register this fragment to listen to event.
		GlobalBus.getBus().register(this);
	}

	private void addFragment() {
		getSupportFragmentManager().beginTransaction()
				.add(R.id.fragmentContainer, new UserFragment())
				.commit();
	}

	public void sendMessageToFragment(View view) {
		EditText etMessage = (EditText) findViewById(R.id.activityData);
		Events.ActivityFragmentMessage activityFragmentMessageEvent =
				new Events.ActivityFragmentMessage(String.valueOf(etMessage.getText()));

		GlobalBus.getBus().post(activityFragmentMessageEvent);
	}

	@Subscribe
	public void getMessage(Events.FragmentActivityMessage fragmentActivityMessage) {
		TextView messageView = (TextView) findViewById(R.id.message);
		messageView.setText(getString(R.string.message_received) + " " + fragmentActivityMessage.getMessage());

		Toast.makeText(getApplicationContext(),
				getString(R.string.message_main_activity) + " " + fragmentActivityMessage.getMessage(),
				Toast.LENGTH_SHORT).show();
	}

	@Override
	protected void onStop() {
		super.onStop();
		GlobalBus.getBus().unregister(this);
	}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/margin_large"
    android:background="#cfcfcf">

    <RelativeLayout
        android:id="@+id/activityLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:padding="@dimen/padding_medium">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/margin_medium"
            android:text="@string/title_main"
            android:textStyle="bold"/>

        <TextView
            android:id="@+id/message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/title"/>

        <EditText
            android:id="@+id/activityData"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/message"
            android:hint="@string/hint_message"/>

        <Button
            android:id="@+id/sendMessageToFragment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/activityData"
            android:layout_centerHorizontal="true"
            android:onClick="sendMessageToFragment"
            android:text="@string/send_message_fragment"/>

    </RelativeLayout>

    <LinearLayout
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/activityLayout"
        android:layout_marginTop="@dimen/margin_extra_large"
        android:orientation="vertical">
    </LinearLayout>

</RelativeLayout>

In MainActivity, We have registered to the EventBus in onStart method and unregistered it in onStop method. Also, MainActivity has subscribed to Events.FragmentActivityMessage event to receive any broadcasted message using this event. Similarly in Fragment, we have registered to the EventBus in onCreateView method and unregistered it in onDestroyView method. Also, it has subscribed to Events.ActivityFragmentMessage event to receive any broadcasted message using this event.




Output

EditText used here are to take input from user and broadcast this message using an event. Then, this message is being shown as toast or inside textview by whoever receive this message. Suppose MainActivity broadcast an event (Events.ActivityFragmentMessage) with message “Hii tutorialwing”. This event will be received by UserFragment since this fragment has subscribed to this event. Now, UserFragment will show the message (“Hii tutorialwing”) in event as toast and as label. You may see the above output for more detail.

This is all about Communication between Activity and Fragment using EventBus library. Similarly, you can write code to broadcast and receive any event in different components in your application.

Similarly, we will show communication between Activity and Activity but with little twist. Here, we will use StickyEvent instead of simple event. Now, you would be wondering what is this stickyEvent, why should we use it and when should we use it? All of the these questions have been explained in this post.

Conclusion

Android EventBus is one of the popular android libraries which is based on publisher/subscriber pattern to communicate between different components in the application.

Support Us

If you have any suggestion about this post, please comment below. We are looking for someone who helps use to make our tutorial better. Also, If you want tutorials on any topic, you can mail us at tutorialwing@gmail.com. We will try to cover the topic as soon as possible. Connect with us on Facebook, Google+, Twitter and Youtube for more updates.