In onCompleted()
Operators
The items emitted by Observables are manipulated before notifying the subscribed Observer object(s). There are many operators available in RxJava including map, filter, reduce, flatmap etc. Let's look at the map example since we are modifying the above example.
- Observable.just(1, 2, 3, 4, 5).map(new Func1<Integer, Integer>() {
- @Override public Integer call(Integer integer) {
- return integer * 3;
- }
- }).subscribe(new Observer<Integer>() {
- @Override public void onCompleted() {
-
- }
-
- @Override public void onError(Throwable e) {
-
- }
-
- @Override public void onNext(Integer integer) {
-
- }
- });
Output produced is every number multiplied by 3 i.e, 3,6,9,12,15.
How it simplifying things.
Network Call - AsyncTask vs RxJava
Let's see the difference between these two approaches. Firstly, we have a very popular and old way to make a network call. AsyncTask has been the traditional way to make calls until fast networking libraries came into the picture.
Create an inner class and extend to AsyncTask, make network operation, and in postExecute(), update the UI. This is the approach this network call uses. Everything seamlessly looks good until the phone rotates. Once the phone is rotated, the code gets blown up and the app gets crashes because the activity recreates itself.
Memory leaks occur in this approach because this inner class has a reference of the outer class. If we want to chain another long operation, then we have to nest the other tasks which will become a non-readable code.
- public class NetworkRequestCall extends AsyncTask<Void, Void, User> {
-
- private final int userId;
-
- public NetworkRequestCall(int userId) {
- this.userId = userId;
- }
-
- @Override protected User doInBackground(Void... params) {
- return networkService.getUserDetails(userId);
- }
-
- @Override protected void onPostExecute(User user) {
- nameTextView.setText(user.getName());
-
- }
- }
-
- private void onButtonClicked(Button button) {
- new NetworkRequestCall(123).execute()
- }
However, in RxJava, this call looks different as shown below.
- private Subscription subscription;
-
- private void onButtonClicked(Button button) {
- subscription = networkService.getObservableUser(123)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(new Action1<User>() {
- @Override public void call(User user) {
- nameTextView.setText(user.getName());
-
- }
- });
- }
-
- @Override protected void onDestroy() {
- if (subscription != null && !subscription.isUnsubscribed()) {
- subscription.unsubscribe();
- }
- super.onDestroy();
- }
In this approach, when an activity is destroyed, we can unsubscribe to the activity. A call does not execute when an activity is destroyed so a potential crash may occur or memory/context leaks are avoided.
In this article, we learned how RxJava is simplifying things. We saw AsyncTask and how RxJava is overcoming the issues with the AsyncTask. There are many other uses cases of RxJava, like in the TimerTask. This Observer and Observable pattern of programming is good enough to deal with the network operations and other cases also.