Android-RxJava: Update UI from background thread using observable

avermaet :

I just started building a simple Android app, in which I'd like to make a network request in a background thread and then update the main thread (UI thread) with the servers response. So far I used AsyncTasks, but future implementations I'd like to use reactive Java (RxJava). I have never done reactive calls before, so I'd like to have a simple but complete example (Observable and Observer creation and subscription) upon which it is possible to further build on.

I managed to include the RxJava dependency into the basic Android project and have written a very simple main activity using AsyncTasks for the network request. Now I tried to substitute the AsyncTask implementation with a reactive one, but got stuck in all the information regarding the Observable and Observer. I'm just not sure what exactly is necessary for a minimum but fully working example.

I'd really apprechiate a bit of help in transforming the main parts into an reactive implementation, since I don't know how to handle the generation of the Observable from the response string and subscribe an Observer.

Thanks.

package com.example.reactiveTest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private Button btnSend = null;
    private TextView result = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.btnSend = findViewById(R.id.button_send);
        this.result = findViewById(R.id.result);
    }

    public void onClickBtnSend(View view) {
        new SomeTask().execute("Just some String");
    }

    class SomeTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... strings) {
            // server request returning response String
            return response;
        }

        @Override
        protected void onPostExecute(String string) {
            // update UI with response String
            result.setText(string);
        }
    }
}
Husayn Hakeem :

With AsyncTask, you're basically performing an asynchronous operation on a worker thread, then using its result on the main thread. In Rx you'd use something like the following:

Observable.fromCallable(asyncOperation)
   .subscribeOn(backgroundThread)
   .observeOn(mainThread)
   .subscribe(result -> { /* update UI for instance */ })

It seems you're also interested in onNext, onError and onComplete.

  • onNext is called every time the observable emits an item. Each time it's called it receives an item, and can then process it.
  • onError is called when the observable has encountered an error for whatever reason. When it's called, it receives a Throwable, which represents the cause of the error. after it's called, onNext and onComplete are not called.
  • onComplete is called after onNext is called with the last item. It doesn't receive any input, you could do some clean up in it for example.

Using the above methods looks like this:

Observable.fromCallable(asyncOperation)
   .subscribeOn(backgroundThread)
   .observeOn(mainThread)
   .subscribe(onNext, onError, onComplete)

[Edit]

If you'd like to create your Observable using Observable.create(), you can definitely do that, it gives you finer control over what and when you emit through the Observable. You can do this for instance if you want to handle some specific errors that can result from your network request, and emit different Throwables depending on the error.

ObservableOnSubscribe asyncOperation = new Observable.OnSubscribe<Integer>() {
    @Override
    public void call(Subscriber<? super Integer> emitter) {
        try {
            // network request
            // Once result is ready, call emitter.onNext().
            // When done, complete this Observable by calling emitter.onComplete()
        } catch (Exception e) {
            // handle error, and emit it using emitter.onError()
        }
    }
 } 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=276700&siteId=1