I have started reading about RxJava / RxAndroid, but I can't find simple tutorial that covers typical thing, like getting network data and updating UI with the result.
Many tutorials cover scenario like running one or more background tasks, that take a parameter and return nothing.
Lets say I have a slow function that may return data or throw an Exception
, like this:
private String getNetworkData(Integer parameter) throws Exception {
Thread.sleep(1000); // simulated delay
switch (parameter) {
case 0: return "Bill";
case 1: return "Joe";
case 2: return "Bob";
case 3: return "Alex";
case 4: return "Mary";
default: throw new Exception("No such user");
}
}
So far, I have written something like this: in my MainActivity I have a button with onClick set like this:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Observable<Integer> observable = Observable
.just(0, 1, 3, 4, 8) // these are call parameters, right?
.subscribeOn(Schedulers.io()) // this is where I do slow work, right?
.observeOn(AndroidSchedulers.mainThread()); // this is where I get results, right?
observable.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d(TAG,"onSubscribe on " + Thread.currentThread().getName());
}
@Override
public void onNext(@NonNull Integer i) {
// what to do with returned?
// how do I catch errors?
String returnedData = getNetworkData(i);
Log.d(TAG,"onNext on " + Thread.currentThread().getName());
}
@Override
public void onError(@NonNull Throwable e) {
// how and where to throw errors that can be processed here?
Log.d(TAG,"onSubscribe on " + Thread.currentThread().getName());
}
@Override
public void onComplete() {
Log.d(TAG,"onComplete on " + Thread.currentThread().getName());
}
});
}
});
The question is: how can I update UI and receive returned data?
I have tried to understand something from this:
but it does not explain anything to me, I have no idea what type is youtubeApi
(is it Observable or what?).
After some discussion in comments under another question I changed my button handler to this:
Callable callable = new Callable<String>() {
@Override
public String call() throws Exception {
Log.d(TAG, "callable called on " + Thread.currentThread().getName());
Thread.sleep(1000); // simulated delay
throw new Exception("Exception!");
// return "Bill";
// this is not what I want, because I can't get any parameter from here
}
};
SingleObserver<String> observer = new SingleObserver<String>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d(TAG, "onSubscribe called on " + Thread.currentThread().getName());
}
@Override
public void onSuccess(@NonNull String s) {
Log.d(TAG, "onSuccess called on " + Thread.currentThread().getName());
}
@Override
public void onError(@NonNull Throwable e) {
Log.d(TAG, "onError called on " + Thread.currentThread().getName());
}
};
Single.fromCallable(callable)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
But now I can't pass a parameter to my slow function.