Android News App Tutorial with Kotlin, RxJava 2, Retrofit 2, Observable.fromIterable() Operator

Fahri Can
6 min readJun 20, 2019

--

Photo by Marvin Meyer on Unsplash

In this blog, I will show you how to use RxJava 2, Kotlin and Retrofit 2 to read data from the News API. Then we will use RxJava 2 to make an Observable of a list and filter specific items in this list. This is an step by step tutorial.

Prerequisites

I assume that you are familiar with Kotlin, Retrofit 2 and Android development. You need an API Key from News API.

Reason to use RxJava 2 with Retrofit 2

RxJava 2 is a great chose whenever working with a large amount of data which also need modification. (If you have to communicate with multiple REST API’s simultaneously, RxJava 2 might be the best option.)

What are the benefits to use RxJava 2 with Retrofit 2 for an API call?

With RxJava 2 operators we can modify different data streams easily.

With RxJava 2 we can avoid multithreading problems easily.

With RxJava 2 we can avoid memory leaks easily.

With RxJava 2 we can write cleaner code easily.

Example App

The tutorial will guide you to create an App. Which allows you to fetch articles from the News API and search for keywords. The change of the items to show will happen with reactive programming.

Gradle dependencies

Go to Android Studio and create a new Empty Project (Language Kotlin, API 19).

Open build.gradle (Module: app) and add the dependencies

Add compileOptions after buildTypes. Otherwise, you can’t run the app. Because when using the latest RxJava 2 Features older Java version before Java 8 can’t handle them.

sourceCompatibility:Language level of the Java source code.

targetCompatibility:Version of the generated Java bytecode.

Add News API Key to string.xml

Create an new string xml file in app -> res -> values

Just name the file api_config.xml

DON’T ADD THIS FILE TO GIT BECAUSE THIS IS YOUR OWN API KEY!

Add api_config.xml to your .gitignore.

Just write at the end of the file api_config.xml

News API

After registering, I have chosen the endpoint “Top headlines”. The endpoint looks like this:

So, just create a data class

An article looks like this:

Then create a data class for Article

And of course, we need a data class for Source

Now the interface for the Endpoint can be defined

Let’s define the layout file (item_article.xml) for the article.

Next step is to create the ViewHolder and Adapter for the RecyclerView

Create a search menu in App

Create menu directory in res, then create a resource file and name it menu_main.xml (res -> menu -> menu).

Using RxJava 2 for fetching articles

Now here is the interesting part, we will use CompositeDisposable, Observable, flatMap, flatMapIterable to display the articles.

First, switch to MainActivity and implement SwipeRefreshLayout

First, we need an Observable of TopHeadlines to fetch a list of articles. The CompositeDisposable is necessary to avoid memory leaks. In our field compositeDisposable are all API calls stored. So we should not forget to dispose all Observables in onDestroy(). I am doing this for safety reason, even if we did not initialized compositeDisposable yet.

Before we can set the attributes in onCreate(), the activity_main.xml needs to be filled.

Now set the attributes in MainActivity.

You can extract the Retrofit.Builder() into a separate method generateRetrofitBuilder() to have a better overview and keep onCreate() shorter. After setting the base URL and GsonConverterFactory, we set the RxJava2CallAdapterFactory. Normally we would set the Call adapter.

Let’s set up the search menu

Let’s take a look at the method checkQueryText(). First, we have to check if the userInput has more than one character. Then we can assign it to our field userKeyWordInput after that we start the getKeyWordQuery(). Where the call to the API happens with the user search input.

When the queryText is not null and empty we set the field userKeywordInput empty. Then we go to our queryTopHeadlines() method, where the call to the API happens for the US articles.

In getKeyWordQuery() when the userKeywordInput is not null and not empty, we save the API call in our topHeadlinesObservable. The API gives us articles which are relevant to the user input. In subscribeObservableOfArticle() happens the RxJava 2 relevant stuff.

In queryTopHeadlines() we first display the loading circle of our swipe_refresh. Then we start the query for the top headlines, with the query parameters “us” and the API key. Here we use the getTopHeadlines() method from our TopHeadlinesEndpoint interface. We store the API call in our topHeadlinesObservable to use reactive programming for changes in the query. In subscribeObservableOfArticle() happens the RxJava 2 relevant stuff.

What happens in subscribeObservableOfArticle() first we have to clear our article list. Every time when the Activity gets into onRefresh() the articleList will be filled with the same articles. Next thing is to add the saved API call from topHeadlinesObservable to the compositeDisposable field. Later we have to dispose of the API calls to avoid memory leaks. On topHeadlinesObservable, we use the method subscribeOn() to specify the Scheduler on which an Observable will operate.

subscribeOn() operator tells the source Observable which thread to emit and push items on all the way down to Observer (hence, it affects both upstream and downstream operators). It does not matter where you put the subscribeOn() in your Observable chain of operators.

Then we put as an argument Schedulers.io() which returns a default, shared Scheduler instance intended for IO-bound work.

IO — This is one of the most common types of Schedulers that are used. They are generally used for IO related stuff. Such as network requests, file system operations. IO scheduler is backed by thread-pool.

observeOn() specifies the Scheduler on which an Observer will observe this Observable. In our case, it happens on AndroidSchedulers.mainThread() the UI-thread. Click here to find more information.

flatMap operator transforms the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable

In other words, we are changing the data stream from data class TopHeadlines to List<Article>.

With Observable.fromIterable(), which is used for Collections we are now getting an Observable of List<Article>

subscribeWith() subscribes a given Observer (subclass) to this Observable and returns the given Observer.

createArticleObserver() in this anonymous class of type DisposableObserver<Article> we first get into onNext(article: Article) and iterate trough the complete list of articles from Observable.fromIterable(it.articles).

If an error occurs we land in onError(e: Throwable) otherwise we land in onComplete() and showArticlesOnRecyclerView().

showArticlesOnRecyclerView() when our class field articleList is empty we hide the RecyclerView. Then display there are no articles found and offer a retry button. If articleList has articles we display all articles with the RecyclerView and hide the TextView and Button element.

Don’t forget the implementation of onRefresh(). Every time a user makes a swipe refresh our checkUserKeywordInput() will be invoked.

Last but not least, don't forget to set the Internet permission in the AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />

Here is the complete project:

--

--

Fahri Can
Fahri Can

Written by Fahri Can

Android Dev | Blogger | AI & Crypto Enthusiast

No responses yet