Learn By Doing Android, Diving into RxJava & RxAndroid (PublishSubject, Map, Function And Debounce)

Shivam Dhuria
4 min readJun 13, 2019

This time we will mimic the functions of a search engine such as Google. On entering an input in the edit text, it fires off a request to fetch the matching results asynchronously. RxJava2 makes it very easy to implement this without having to worry about AsyncTasks or Threadpools.

Before proceeding, you need to be aware of the basics of RxJava(mainly Observers,Observables and Concurrency) to get a full understanding of the working of this app.

Learn By Doing

Let’s create mock client first, which send us the List of Strings that matches with the search String.

RestClient.java

To keep this article short, I wouldn’t set up the layout or the RecyclerViewAdapter. You can find that in my repository.

What is a Subject

At this point you should be aware that observables emit values, and observers consume them. So where does a Subject fit in?

A Subject is both an Observer and and an Observable! As an Observable, it can pass through the items it observes by re-emitting them, and it can also emit new items.You can use it to convert Cold observables into Hot Observables.

Analogy

Consider the Observable to be a Musician(emitter) and the audience as the Observer(consumer). In this case the subject will act like a tape recorder with player. It can listen(observe/record) to the singer and can also play(emit) like an observable. You can also add new songs from some other artist onto it.

We’ll only use PublishSubject in this application. Think of it as as the same tape recorder/player that always keeps playing the tracks.There are no play/pause/rewind/forward buttons. You can only listen to the track from the time when you connect(subscribe) your earphones to it.

What is a Map

A map operator is used to basically transform the the observable item and emit the modified item by applying a function to each item.(Read More)

The function below returns a square of the original item.

.map(x -> x * x)

Enough with the theory, let’s start making this application now.Let’s create an Observable of PublishSubject of String type . We’ll need it to be global and initialize it in onCreate().

private PublishSubject<String> mPublishSubject;
private CompositeDisposable disposables;

mPublishSubject as an observer.

Since mPublishSubject can act as an observer, it has an onNext() method. Whenever the text in the editTextView changes, I pass the search query(String) in the onNext() method. Continuing with the analogy above, this is the tape recorder recording the music.

Now it is time to define a function.

A functional interface that takes a value and returns another value, possibly with a different type and allows throwing a checked exception.

This function takes in a String value, and returns an list of Strings that it fetches from the rest client.We’ll need this for the .map operator.

mPublishSubject as an observable.

As an observer it consumes a String query(passed from .onNext(String s)), and as an observable it emits that value on which we use .map(searchString) operator which takes in a String query and returns a list of matching Strings(fetched from restClient)on the IO thread provided by the scheduler which we observe on the mainThread.

We subscribe it to a new Observer which handles this returned list of strings in onNext(). From there we can can display these strings in the recyclerview.

Debounce

To make our search feature better, we’ll use the debounce operator. As the user might input/change lots of characters rapidly, we’ll end up sending lots of requests to the client for each modification in the query(Every single character addition/removal will send a new request). To reduce the number of requests, we’ll use the debounce operator.

Debounce essentially waits for a certain duration(400 milli seconds in this case) before emitting an item(say “A”). However if the observable emits another item(say “ABC”) before the 400 ms interval, it won’t emit the original item(“A”). Now it will only emit this new item(“ABC”) if no new item is emitted in next the 400 ms interval.

mPublishSubject
//Add this line
.debounce(400, TimeUnit.MILLISECONDS)
.map(searchString)

Here’s how my whole activity should look like. Make sure you clear the disposables in onDestroy.

You can find this repository on my github.

--

--