← All Articles

Consuming a JSON API - Part 2 (EventBus)

Previously we looked at how to use Retrofit to make requests to a JSON API. In this article, I'm going to show how to use EventBus to update the rest of your app once the API returns a response.

Adding EventBus

First, include compile 'de.greenrobot:eventbus:2.4.0' to your gradle file. This then lets you post and listen to particular events.

In part 1, we had a Submission class with a fetchComments() method. In the success callback of this method, we post a new CommentsReceived event (more on this later). This is what it looks like:


public class Submission(){
  // Other class methods etc

  public void fetchComments(){

    // other parts of the method
    // ....

    api.getComments(this.forum, this.id, new Callback() {
      @Override
      public void success(CommentsResponse commentsResponse, Response response) {
        comments = commentsResponse.data;
        EventBus.getDefault().post(new CommentsReceived(comments));
      }

    });

  }

 So when the API responds with the comments data, we are posting a new CommentsReceived event with the comments data.

Creating Events

What is this CommentsReceived event? It's nothing more than a simple class, with any extra data you want included. In this case, we are adding the comments data from the API response.

I like to group my events in an events folder, so my events/CommentsReceived.java looks like this:


package my.app.name.events;

import java.util.List;

import my.app.name.models.Comment;

public class CommentsReceived {

  public List comments;

  public CommentsReceived(List comments) {
    this.comments = comments;
  }

}

Remember, so long as our Comments model has attributes matching the JSON keys returned in the API response, we can instantiate these as Comments instances.

Consuming Events

Now that we have posted a CommentsReceived event, what do we do with it? Well, our activities can listen out for these events and process the data (for example, updating the screen, or storing in your local datastore, etc). 

Let's say we have a SubmissionActivity and we want to update a content adapter with these comments, so that the listview of comments is updated.

First we make sure to register the activity with EventBus, and also unregister when the activity is paused (otherwise it may behave erratically if it receives an event when it is not active). Finally, we listen out for the CommentsReceived event.


package my.app.name.activities;

// other import items not shown here
import my.app.name.CommentsReceived;


public class SubmissionActivity extends BaseActivity {
  // other activity methods and attributes not shown here

  @Override
  public void onResume() {
    super.onResume();
    EventBus.getDefault().register(this);
  }

  @Override
  public void onPause() {
    super.onPause();
    EventBus.getDefault().unregister(this);
  }

  public void onEventMainThread(CommentsReceived event) {

    if ( event.comments.isEmpty() ){
      mAdapter.setNotice("No comments yet :(");
    }

    else {
      mComments = event.comments;
      for (Comment c : mComments){ mAdapter.addItem(c); }
    }
    mAdapter.notifyDataSetChanged();
  }
}

That's pretty much it. Our app now consumes a JSON API with Retrofit and also uses EventBus to update various screens.

Made with JoyBird