making api calls with retrofit rxjava complete app

Connect to an API With Retrofit, RxJava 2, and Kotlin

Today, it’s pretty common for mobile apps to exchange data with remote servers, using web Application Programming Interfaces (APIs).

Whether it’s checking for new emails using the Gmail API, searching for events in the local area with the Ticketmaster API, or leveraging the user’s Spotify history to recommend new music, APIs (usually REST APIs) provide access to a wealth of information that you can use in your app.

Communicating with remote servers has become such an important part of modern mobile development that there are countless libraries dedicated to helping you make network calls, but Retrofit is one of the most widely used networking libraries for Android. 

In this article, I’ll show you how to retrieve data from a remote API, using Retrofit and the free Nomics Cryptocurrency & Bitcoin API. 

Once you’ve retrieved some data, you’ll want to put it to good use! In Android, this often involves forwarding the data to Android’s all-important main UI thread, ready to display in your app’s UI, or transforming the data in some way, such as filtering or combining it. Conveniently, you can do all of these things with the RxJava library, so we’ll be using Retrofit and RxJava side by side in our project. 

By the end of this article, you’ll have created an app that retrieves data from a remote API using Retrofit, converts that data into RxJava’s Observable format, and then manipulates that data using a selection of RxJava and RxAndroid operators and schedulers. 

What We’ll Be Building

There’s no shortage of APIs out there, but to help keep things straightforward, we’ll be using the free Nomics Cryptocurrency & Bitcoin API to retrieve a list of cryptocurrencies and their market prices for the last recorded trade. I’ll then use a RecyclerView to display this information in our app. 

The finished app will display data retrieved from the Nomics Cryptocurrency  Bitcoin API

To issue a Retrofit request, we’ll need to create the following: 

  • A Retrofit class. This is where you’ll create a Retrofit instance, add a converter (we’ll be using Gson), and then specify the base URL that your app should use for all of its HTTP requests. 
  • A data class. This class represents the responses for each of your app’s API calls. 
  • An API interface. This is where you describe each Retrofit request that you want to make.

By the end of this tutorial, you’ll have a project that looks something like this:

The finished project structure will consist of a Retrofit class data class API interface and an adapter to display the UI

Why Should I Use RxJava for My API Calls?

RxJava is an open-source, JVM-compatible implementation of the ReactiveX library that’s designed to help you work with asynchronous streams of data in a reactive programming style, and without having to write a ton of callbacks. 

There are many benefits to using RxJava in your Android projects, but some of the most important include:

  • Simplified code. RxJava lets you describe what you want to achieve, rather than writing a list of instructions for your application to work through. This approach typically results in more concise, human-readable code that’s easier to maintain and less prone to errors. 
  • Consistency. RxJava may be a data-focused library, but its definition of “data” is pretty broad and includes things like variables, caches, properties, and even user input events such as clicks and swipes. Since RxJava treats pretty much everything as data, it provides a consistent workflow that you can use across your application, in lots of different scenarios. 
  • Multithreading made easy. Modern mobile apps must be able to multitask, but as a single-threaded environment, Android isn’t exactly a natural born multitasker! Android does provide several built-in tools for creating additional threads, but none of these solutions are particularly easy to work with, and they can quickly result in complex code that’s susceptible to performance problems such as memory leaks. By adding RxJava to your project, you get access to subscribeOn and observeOn operators, which make it much easier to create and manage additional threads. 
  • Complex data transformations. RxJava has an enormous collection of operators that you can use to modify, filter, merge and transform the data that’s being emitted by your RxJava Observables. Applying an operator to an Observable typically returns another Observable, so if you can’t find the perfect operator for your project, then you can just keep applying operators to an Observable until you get exactly the results you want. 

For more information about the benefits of using RxJava in your Android projects, check out our Get Started With RxJava 2 article.

Authenticating With an API Key 

Many APIs require you to include a unique API key in your HTTP requests. These keys allow the company or individual behind the API to track the requests associated with your project, which is handy for enforcing usage restrictions or if the API’s creator simply wants some insight into how their API is being used.

When querying the Nomics Cryptocurrency & Bitcoin API, you’ll need to incorporate a unique API key into your request, so let’s generate this key now:

  • In your web browser, head over to the Nomics website.
  • Find the Get Free API Key button, and give it a click. 
  • Check the Terms and Conditions, and if you’re happy to proceed then complete the form.
  • Select Complete Order. After a few moments, you should receive an email containing your unique API key. 

Create Your Application: Adding Dependencies 

Create a new Android application with the settings of your choice, but when prompted, opt to Include Kotlin support

Next, open your build.gradle file and add all the libraries we’ll be using throughout this project. In addition to Retrofit and RxJava 2.0, we’ll need the following: 

1. RecyclerView

After retrieving our data, we’ll display it in a list, using RecyclerView.

2. Gson Converter

Most of the time, the server’s response will be mapped to a language-neutral format, such as JSON, so your app will need to serialize and deserialize the JSON data. Out of the box, Retrofit can only deserialize HTTP bodies into OkHttp’s ResponseBody type, but you can support other types by outsourcing the conversion to independent converters. 

There’s a wide range of converters available, but in this tutorial I’ll be using Gson, which converts JSON into the equivalent Java objects. 

3. The RxJava Adapter

To create interface methods that are capable of returning RxJava types, we’ll need to use the Retrofit adapter for RxJava. 

4. The RxAndroid Library

The RxAndroid library provides some Android specific bindings for RxJava, most notably AndroidSchedulers.mainThread

In Android, you can only update your app’s UI from the main UI thread. If your users are going to see any cryptocurrency data, then you’ll need to switch to the main UI thread at some point. 

You can quickly and easily schedule code to run on Android’s main UI thread by using RxJava’s observeOn operator in combination with RxAndroid’s AndroidSchedulers.mainThread scheduler:

To use RxAndroid in your project, you’ll need the following project dependency:

… But Not RxKotlin

At this point, you may be wondering why we’re coding in Kotlin but using RxJava, when there is a dedicated RxKotlin library available. 

Since Kotlin is 100% interoperable with Java, the majority of Java libraries are compatible with Kotlin, and RxJava is no exception! You could use RxJava and RxKotlin in your project, but to help keep things simple, I’ll be sticking to RxJava throughout this tutorial. If you’re interested in learning more about RxKotlin, then you’ll find lots of information in my article on Kotlin Reactive Programming With RxJava and RxKotlin.

Add the Project Dependencies 

After adding all these project dependencies, your build.gradle file should look something like this: 

Request Access to the Internet 

Since our app will be communicating with a remote server, it needs permission to access the Internet. Open your project’s Manifest and add the following: 

Note that since android.permission.INTERNET is categorised as a safe permission, we don’t need to request it at runtime. 

Define Your HTTP Endpoints

Next, we need to create an interface where we describe our HTTP requests:

  • Select File > New > Kotlin File/Class from the Android Studio toolbar.
  • Name this file GetData.
  • Open the dropdown menu, and select Interface.
Create a new interface by selecting File  New  Kotlin FileClass from Android Studios toolbar
  • Click OK.

Each request needs to include at least one HTTP annotation, which indicates how this request should be handled. Retrofit supports annotations for all the standard request types, but we’ll only be using the @GET annotation, since we’re retrieving data from the server. 

We also need to describe the endpoint, which is the URL we’re retrieving data from. In our app, this is https://api.nomics.com/v1/markets/prices, which consists of a base URL (https://api.nomics.com/v1/) and a relative URL (prices). We’ll define the base URL elsewhere in our project, so for now we just need to worry about the relative URL.

If the API in question doesn’t require an API key, then declaring the base and relative URL should be enough, but since the Nomics API does require a key, we need to incorporate this information into our request. 

This process can vary between APIs, so you should always refer to your API’s documentation for more information. In particular, be on the lookout for any section marked Authentication, as this is often where you’ll find instructions relating to API keys. The Nomics API documentation is a perfect example of this, as it has a dedicated Authentication section that describes how you should incorporate your key in the following format: 

https://api.nomics.com/v1/prices?key=your-api-key-goes-here

Combining the @GET annotation, relative URL, and your API key gives us the following:

I’ll fetch the API data using Kotlin’s getData() function. Since we want this function to emit RxJava Observables, we need to define our endpoint as a valid RxJava type:

Here’s the completed interface: 

Make sure you replace YOUR-API-KEY-HERE with your own key! 

Creating a Model With Kotlin’s Data Class

Next, we need to create a data class that represents the response to each of our API calls:

  • Select File > New > Kotlin File / Class from the Android Studio toolbar. 
  • Name this class RetroCrypto, and then click OK.
  • Open your new RetroCrypto class.

If you’ve previously performed Retrofit calls using Java, then this is one area where Kotlin is much more concise than the equivalent Java, thanks to data classes.

In Kotlin, a data class is a class that’s designed solely to hold some data. The Kotlin compiler implements the required hashCode(), equals() and toString() methods automatically, so you can create a data model class in a single line of code. 

Open your new RetroCrypto file and add the following:

Building the Retrofit Instance 

To send network requests, we need to use the Retrofit.Builder class to create a Retrofit instance, where we’ll call our endpoint and retrieve the cryptocurrency information. 

Once we’ve built our Retrofit object, we need to:

  • Set the base URL. Before you can call the build() method on Retrofit.Builder, you need to have at least defined the base URL.
  • Set the default converter, using the addConverterFactory() method. Once you’ve set up the Gson converter, it’ll translate the JSON response for you automatically. 
  • Apply the adapter. Retrofit ships with a default adapter for executing Call instances, but you can apply one or more additional adapters by supplying an instance of that adapter when you’re building the Retrofit instance. To use RxJava alongside Retrofit, we need to add RxJava2CallAdapterFactory as the call adapter, using .addCallAdapterFactory

This gives us the following:

By default, an Observable emits its data on the thread where the subscription was declared, which in Android is typically the main UI thread. However, for the best results, your app should only perform UI-related work on the UI thread, so we’ll be using RxJava’s subscribeOn and an accompanying Scheduler to create an alternative thread where the Observable should execute:

Next, we’ll use the observeOn operator, plus RxAndroid’s AndroidSchedulers.mainThread Scheduler to send the Observable’s notifications to Android’s main UI thread, ready to display the retrieved data in our app’s UI.

For a more detailed look at subscribing to Observables in Kotlin, check out my post on Kotlin Reactive Programming With RxJava and RxKotlin.

In the following snippet, I’m also using the handleResponse() method to handle the data we’ll receive, following a successful network operation:

The above code returns a Disposable—if you have previous experience of RxJava 1.0, then disposables are essentially RxJava 2.0’s version of subscriptions.

When you’ve finished with a disposable/subscription, you must dispose of it to avoid memory leaks. We can make this cleanup process easier by adding all of our disposables to a CompositeDisposable, which is a container that can hold multiple disposables. In the above code, we’re initializing RxJava’s CompositeDisposable, and then adding each disposable to the CompositeDisposable, using the add() method. 

Then, we simply need to clear the CompositeDisposable during our project’s onDestroy() method: 

Here’s the completed class: 

Displaying the Cryptocurrency API Data 

At this point, our app can successfully retrieve data from the Nomics API, so our final task is displaying this data to the user, via a RecyclerView. 

To implement a RecyclerView, we need the following:

  • A RecyclerView widget.
  • A custom XML layout that the RecyclerView can use to display each of its items. 
  • An adapter, which binds the data to your RecyclerView

Creating a Scrollable List 

Let’s start by adding a RecyclerView widget to our activity_main.xml file:

Now that we have our RecyclerView widget, we need to define the layout for each row within that RecyclerView. I’m going to create a simple layout consisting of two TextViews, where I’ll display the name and the price for each cryptocurrency retrieved from the Nomics API:

  • Control-click your project’s res/layout folder.
  • Select New > Layout resource file.
  • Name this file row_layout, and then click OK.
Create a row_layoutxml file where well define the layout of each item in our RecylerView

Open the row_layout.xml file, and add the following: 

Our RecyclerView will now use this layout for each item in our list. 

Binding Data With Android Adapters 

The adapter is the component that’s responsible for binding each item to a View within the RecyclerView

To connect the underlying data model to your app’s UI, you need to extend RecyclerView.Adapter, and then implement the following:

  • onCreateViewHolder(). This is where we specify the layout (R.layout.row_layout) that each item in the RecyclerView should use, and inflate that layout using LayoutInflater.
  • onBindViewHolder(). Called by RecyclerView to display the data at the specified position.
  • getItemCount(). Returns the number of items present in the data set.

When you’re working with Views, you can often simplify your code by using Kotlin Android extensions. These extensions allow you to access a layout’s Views directly, by importing them into your class as “synthetic” properties. For example, you can import references to all the Views within your row_layout file, using the following:

At this point, you can access all of row_layout’s Views, using just their IDs—and without a findViewById() in sight! For example, you can update the text_name widget, using the following:

In this class, I’ll also pass the data as an ArrayList, along with a Listener that I’ll use to handle user input events. Finally, to make our app look a little more interesting, I’ll define an Array of colours and then use them as the background for my RecyclerView items.

Create a new Kotlin class named MyAdapter and then add the following: 

Testing Your Retrofit and RxJava 2.0 App

Now it’s time to put your application to the test! Make sure you have an active Internet connection, and then install your app on an Android smartphone or tablet or AVD (Android Virtual Device). As soon as your app launches, Retrofit will retrieve all the available data from the Nomics API, and then display it as part of your RecyclerView

The finished user interface complete with data retrieved from a remote API

You can also download the completed project from our GitHub repo.

Conclusion 

In this article, I showed you how to retrieve data from an API using Retrofit, convert that data into RxJava 2.0’s Observable format, and then display it in a RecyclerView

If you want to explore more APIs, then you’ll find a list of free, public APIs over at GitHub, or you can learn more about RxJava by checking out our series on Getting Started With RxJava 2 for Android, or by taking a look at our Kotlin Reactive Programming series.

Powered by WPeMatico

Leave a Comment

Scroll to Top