Asynchronous processing by RxJava (RxAndroid) on Android

Introduction

Last time, I talked about creating a sample app in the following article. RxJava (RxAndroid) + RxBus + Data Binding + room sample (based on Java 1.7) on Android.

This time, I will explain the implementation that uses RxJava to get data asynchronously from the API. Please refer to the previous article above for the operating environment.

Necessity of asynchronous processing by Android application

When trying to get data from an API that exists on the web Processing may take some time depending on the communication status and the amount of data. During this time, if operations on the screen (cancellation, etc.) are not accepted, the UX will deteriorate, so Processing that may take time is generally done asynchronously.

Library for realizing asynchronous processing

There are several libraries on Android that enable this asynchronous process.

I used RxJava this time, You may consider using other libraries such as LiveData. By the way, the reason I chose RxJava is I thought that there were many usage examples and many cases, This is because I thought it was "withered" compared to LiveData.

Prerequisites

This time, I will not explain about Reactive Programming or RxJava. For more details, if you google, you will get various hits, so there ...

Also, for the time being, only the minimum necessary explanation is given to move, so When using it for business purposes, please be sure to check it **.

Realization and explanation of asynchronous processing by RxJava.

You can refer to the explanation source here.

GitHub SampleAndroidApps

API execution side processing (monitored side Observer)

The corresponding source is here

    Observable.create(new ObservableOnSubscribe<GithubRepositoryApiResponseEntity>() {
        @Override
        public void subscribe(ObservableEmitter<GithubRepositoryApiResponseEntity> emitter) throws Exception {
    
            //Asynchronous processing
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .build();
    
            OkHttpClient client = new OkHttpClient();
            try {
                Response res = client.newCall(request).execute();
                String responseBodyStr = res.body().string();
                //Objectize json with GSON
                Gson gson = new Gson();
                GithubRepositoryApiResponseEntity responceData = (GithubRepositoryApiResponseEntity) gson.fromJson(responseBodyStr, GithubRepositoryApiResponseEntity.class);
                emitter.onNext(responceData);
                emitter.onComplete();
            } catch (Exception e) {
                e.printStackTrace();
                emitter.onError(e);
            } finally {
                loading = false;
            }
        }
    })
    .observeOn(Schedulers.newThread())  //after observeOn(response)Do it in a new thread
    .subscribeOn(Schedulers.newThread())       //Do it asynchronously in a new thread
    .subscribe(observer);             //Execute

Pass an anonymous class of type ObservableOnSubscribe to Observable.create. For ObservableOnSubscribe, specify the type of object to be sent to Stream (result received by Observer). Write the process you want to make asynchronous in the subscribe method. (This time, the process of hitting the API to get the Repository of GitHub)

In emitter.onNext, specify the stream (result received by the Observer). Then don't forget to call ʻemitter.onComplete ();. The abnormal system is ʻemitter.onError (Exception);.

Pass the result of Observable.create to observeOn and Specifies the thread to process. ʻIf you specify AndroidSchedulers.mainThread (), it will run on the main thread. If you specify Schedulers. newThread ()`, it will run on a new thread (which does not interfere with the main thread).

Finally, specify the observer in the subscribe method and register.

Processing on the side that received the API execution result (Observer on the monitoring side)

The corresponding source is here

    private Observer observer = new Observer<GithubRepositoryApiResponseEntity>() {
        GithubRepositoryApiCompleteEventEntity eventResult = new GithubRepositoryApiCompleteEventEntity();
    
        @Override
        public void onSubscribe(Disposable d) {
    
        }
    
        @Override
        public void onNext(GithubRepositoryApiResponseEntity response) {
            eventResult.setResult(false);
    
            List<GithubRepositoryApiResponseEntity.Repository> repositoryList = response.getItems();
            ArrayList<GithubRepositoryListItemEntity> data = new ArrayList<>();
            for (GithubRepositoryApiResponseEntity.Repository repository : repositoryList) {
                GithubRepositoryListItemEntity listItem = new GithubRepositoryListItemEntity();
                listItem.setFullName(repository.getFull_name());
                data.add(listItem);
            }
    
            eventResult.setListItems(data);
            if (response.getItems() != null && response.getItems().size() > 0) {
                eventResult.setResult(true);
            }
    
            //Call an event
            RxBus.getInstance().send(eventResult);
        }
    
        @Override
        public void onError(Throwable e) {
            //Call an event
            RxBus.getInstance().send(eventResult);
        }
    
        @Override
        public void onComplete() {
    
        }
    };

First, I will explain the following RxBus next time. RxBus.getInstance().send(eventResult);

First, define an instance of type Observer . T specifies the type of object flowing from the Observable.

onSubscribe is a method that is executed when the data is ready. Notification can be canceled using the argument Disposable (It is unknown whether it is meaningful to release at this timing ...)

onNext is a method that is executed when data flows. This time you only receive the API results once. In this sample, it is replaced with Entity class for display, I think it is unnecessary if Gson and Data Binding can be defined as a set. (I thought it wasn't so fatal, so I left it as it was)

onError is a method called when an error occurs. I haven't processed it in this sample, so Do something if you need to.

onComplete is a method that is executed when the data flow is finished.

It was like this.

About life cycle

The ViewModel is persistent (holding an instance in a subclass of Application), so Basically, I don't think there is any impact from the life cycle. However, it has an effect when View (Activity and Fragment) is involved.

in conclusion

That's why it was a brief explanation of asynchronous processing by RxJava. It seems to be difficult to use RxJava for various things. For the time being, from the current legacy code, It seems feasible to replace asynchronous processing.

Next time, I would like to explain event notification by RxBus.

Recommended Posts

Asynchronous processing by RxJava (RxAndroid) on Android
Notes on Android (java) thread processing
RxJava (RxAndroid) + RxBus + Data Binding + room sample (based on Java1.7) on Android.
Basic basis of Android asynchronous processing "AsyncTask"
About UI thread processing in Android asynchronous
Asynchronous processing and Web API integration in Android Studio
[Swift] Asynchronous processing "GCD"
[Android] Notes on xml
Run Processing on Ant
About truncation by the number of bytes of String on Android