Reputation: 1593
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);
}
}
}
Upvotes: 3
Views: 2639
Reputation: 4570
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 Throwable
s 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()
}
}
}
Upvotes: 4