Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to handle RxAndroid errors in the main thread

I'm new to rxJava/Android and surprised that my onError lambda is sometimes called on the main-thread and sometimes not, although I use .observeOn(AndroidSchedulers.mainThread())

Example 1: onError on main-thread
this works as expected: onError is called on the main-thread

Observable.error(new RuntimeException("RTE"))
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(s -> {
                Log.e(TAG, "onNext("+s+")-thread: " + Thread.currentThread().getName());
            },
            throwable -> {
                Log.e(TAG, "onError()-thread: " + Thread.currentThread().getName());
            });

log-output:

onError()-thread: main

Example 2: onError NOT on main-thread

Observable.create(new Observable.OnSubscribe<String>() {
    @Override
    public void call(Subscriber<? super String> subscriber) {
        subscriber.onNext("one and only");
    }
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.timeout(1, TimeUnit.SECONDS)
.subscribe(s -> {
        Log.e(TAG, "onNext("+s+")-thread: " + Thread.currentThread().getName());
    },
    throwable -> {
        Log.e(TAG, "onError()-thread: " + Thread.currentThread().getName());
    });

the output is something like this:

onNext(one and only)-thread: main
onError()-thread: RxComputationScheduler-4       

I thought that after calling observeOn(AndroidSchedulers.mainThread()), ALL emissions should be done on the main-thread.

so I have these questions:

  1. I could not find any documentation that specifies under what circumstances onError is called in which thread. Anyone knows a link?
  2. I do of course want to display some error-indication in the GUI: so how can I force onError to be ALWAYS called in the main-thread?
like image 580
TmTron Avatar asked Oct 03 '16 16:10

TmTron


People also ask

How will you handle error in RxJava?

Here, in the above code we see as soon as we get an exception in map operator and then we directly goto onError and the onNext doesn't get called or even onComplete. So, to handle the error in cases like this we use different operators and it will not move to onError directly. Let us understand them one by one.

What is RxAndroid?

What is RxAndroid? RxAndroid is an extension of RxJava for Android which is used only in Android application. RxAndroid introduced the Main Thread required for Android. To work with the multithreading in Android, we will need the Looper and Handler for Main Thread execution. RxAndroid provides AndroidSchedulers.

What is Reactivex RxAndroid?

RxAndroid: Reactive Extensions for AndroidThis module adds the minimum classes to RxJava that make writing reactive components in Android applications easy and hassle-free. More specifically, it provides a Scheduler that schedules on the main thread or any given Looper .

Is RxJava a thread?

RxJava is NOT Multi-Threaded by Default RxJava, by default, is not multi-threaded in any way. The definition given for RxJava on their official website is as follows: A library for composing asynchronous and event-based programs using observable sequences for the Java VM.


1 Answers

I just found out that I only need to change the order of calls. When I call observeOn after timeout it works as expected:

.timeout(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())

log-output

onNext(one and only)-thread: main
onError()-thread: main

The reason is, that observeOn will only affect everything below the call, and only until some other operator changes the thread again. In the example above, timeout() will change to the computation thread.

Note, that subscribeOn works differently. It does not matter where in the chain you call it.
You should only call it once (when you call it multiple times the first call wins: see "Multiple subscribeOn" in this Blog)

Here is a nice blog-post with more details: RxJava- Understanding observeOn() and subscribeOn()

like image 197
TmTron Avatar answered Sep 28 '22 06:09

TmTron