Let’s take a typical case in our Android applications: searching for a user in our web service, based on a text entered by the user.
For that, we add a TextWatcher on our EditText, and so as soon as text changes, we call our web service so that it returns us the users whose name contains the entered text.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { String name = s.toString(); if(name.length() > 3) { //here is where we call the web service to search for the text webservice.searchUser(name) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(users -> { recyclerAdapter.displayUsers(users); }); } } }); |
The render will be kind of slow since, for each letter removed/added, it makes a call to the web service.
RxBindings
Let’s add the RxBindings library to our build.gradle
1 |
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0' |
Then use RxTextView.textChanges on our editText instead of addTextChangedListener
1 2 3 4 5 6 7 8 9 10 11 12 |
RxTextView.textChanges(editText) .map(CharSequence::toString) .filter(text -> text.length() > 3) .flatMap(text -> webservice.search(text)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(users -> { recyclerAdapter.displayUsers(users); }); |
Limit network calls
We will use an Rx flow management operator to limit calls to our web service.
Here, the use of throttleWithTimeout will make sure to take into account only one change of text (more than three characters) every 5 seconds.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
RxTextView.textChanges(editText) .map(CharSequence::toString) .filter(text -> text.length() > 3) //only takes a value each 5 seconds .throttleWithTimeout(5, TimeUnit.SECONDS) .flatMap(webservice::search) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(recyclerAdapter::displayUsers); |
The interface will be more fluid, and it will limit the use of bandwidth (it’s better for the users who uses 3g).