In this tutorial, we will learn how to use Guava EventBus Library in android application. We will learn about how does eventBus library work? How to use eventBus library to communicate between two fragments, between fragment and activity etc.?
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.
Android EventBus Library 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, EventBus Library speeds up application and make application easily debuggable.
Output
Video Output
Source Code
Android Guava EventBus Tutorial Source Code
1. Getting Started
In this tutorial, we will learn how to use eventBus 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 Library
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? Learn more about Advance Concepts in Android EventBus.
Conclusion
Android EventBus Library is one of the popular android libraries which is based on publisher/subscriber pattern to communicate between different components in the application i.e. you can communicate between fragment and activity or between different fragments etc.
You must be logged in to post a comment.