RxJava, Retrofit and Databindings on Android

In this post I will showcase how you can combine RxJava, Retrofit and Android Databindings to do a simple lookup of country from a country code.

The goal here is to avoid the very bloated activity/fragment classes we see in a lot of project and in general make the app easier to test and maintain.

The source code referenced in this post can be found at github.

I’m using the open and free https://restcountries.eu/rest/v1/callingcode/7 since its just that, open and free. Also it is quite nice and easy to use.

The app is supposed to do the following:

  1. accept input from the user in the form of digits (a CCC)
  2. when “Search” button is clicked, fetch data from restcountries api
  3. transform the data into a simple string
  4. show the string in a textview

So lets start with the click on the Search button. In the xml layout definition of the search button we add a oneliner to bind the onClick action to a method call on our ViewModel object.

android:onClick="@{() -> viewModel.onSearchClick()}"

The ViewModel is injected by the databinding framework given that we specify that we want access to it in the layout xml.

If this is confusing you should go and read up on databindings for android, link above.

Once the onClick calls MainViewModel.onSearchClick() we get to the more interesting stuff.

public void onSearchClick() {
            .subscribe(new Subscriber>() {
                public final void onNext(@NonNull List countryDataList) {

And the actual rest call.

public interface RestCountriesService {
    String SERVICE_ENDPOINT = "https://restcountries.eu/";

    Observable> getRestCountriesCallingCode(@Path("ccc") String ccc);

Using retrofit the rest call is one line of annotation and once line of interface declaration, cant be much simpler than this. When the rest call returns a result from the restcountries api this result will be dropped into the world of RxJava in the form of a Observable<List<CountryData>> that we already subscribed a Subscriber<List<CountryData>> to. The actual api call will be done on a separate thread and the result will be observed on the main thread, just like we are used to with async tasks and other similar constructs. The Subscriber has a couple of callback methods that will be used as the result is observed, the onNext callback is the only one we will pay attention to at the moment.

public final void onNext(@NonNull List countryDataList) {
    Observable.from(countryDataList).map(countryData -> countryData.name)
            .reduce((accumulator, name) -> accumulator + " - " + name)
            .subscribe(names -> setNames(names));

onNext receives a List of CountryData. To handle this list we will make a Observable of it that will emit the CountryData objects one after another. Using the map function we will pick the only piece of information that we are interested in from the CountryData objects, the name string. Then we will use reduce to concatenate the name strings into one string and the set that string to the names variable of the ViewModel where the databinding library takes over and updates the ui.

Just to make things clear, one goal is to avoid the very bloated activity/fragment classes I see all to often, here is the MainActivity, and it is expected to stay that size independent of what views and businesses logic we add to the activity.

public class MainActivity extends ViewModelActivity {

    private MainViewModel mainViewModel;

    protected void onCreate(Bundle savedInstanceState) {

        se.kjellstrand.worldbankdata.databinding.ActivityMainBinding binding =
                DataBindingUtil.setContentView(this, R.layout.activity_main);

    protected ViewModel createViewModel(ViewModel.State savedViewModelState) {
        mainViewModel = new MainViewModel(savedViewModelState);
        return mainViewModel;

Comments on how to improve on this and what potential pitfalls I’m setting myself up for are most welcome.

This Post Has 2 Comments

  1. Hemant Sharma


    Good post.

    What is better for testing:
    1. Hardcoding actions in xml.
    2. Use Rx bindings.

    1. Carl-Emil Kjellstrand

      Hi Hemant,

      I don’t know, have still to figure that out for myself. But I would think that using Rx bindings should work well.

Leave a Reply