ReactiveX / RxAndroid

RxJava bindings for Android
Apache License 2.0
19.89k stars 2.94k forks source link

Operators running on the main thread by default. #392

Closed SarthakM9 closed 7 years ago

SarthakM9 commented 7 years ago

Consider this code:

RxTextView.afterTextChangeEvents(editText)
        .subscribeOn(Schedulers.io())
        .skip(1)
        .map({ input ->
            Log.i("MAPPING ON:", Thread.currentThread().name)
            // some code
        })
        .debounce(2, TimeUnit.SECONDS)
        .subscribe {
            Log.i("SUBSCRIBED ON:", Thread.currentThread().name)
            // some code
        }

and this is the log that gets printed:

I/MAPPING ON:: main
I/SUBSCRIBED ON:: RxComputationThreadPool-1

Why is map operator being called on main thread? Shouldn't the map operator and subscribe function be called on IO thread? Where is Computation thread coming from?

And, if I add observeOn(Schedulers.io()) just below subscribeOn():

I/MAPPING ON:: RxCachedThreadScheduler-3
I/SUBSCRIBED ON:: RxComputationThreadPool-1

now map operator gets called on IO thread but subscribe is still getting called on Computation thread.

I would happily move this question to SO if it is just my misunderstanding and not an issue.

Versions I am using: rx_java = '2.0.7' rx_android = '2.0.1' rx_binding_kotlin = '2.0.0'

artem-zinnatullin commented 7 years ago

SubscribeOn controls the subscription thread, but does not control the emission thread.

In your case you subscribe on io, you should not do that because Android Framework expects you to work with Views on the threads they were created on (main in your case). And it's not going to prevent afterTextChange events from emitting on main thread, RxJava has observeOn for that.

Computation thread comes from Computation scheduler used as a default scheduler by debounce operator.

This is not a bug and it's not directly related to RxAndroid.

On Tue, Aug 22, 2017, 1:22 AM Sarthak Mittal notifications@github.com wrote:

Consider this code:

RxTextView.afterTextChangeEvents(editText) .subscribeOn(Schedulers.io()) .skip(1) .map({ input -> Log.i("MAPPING ON:", Thread.currentThread().name) // some code }) .debounce(2, TimeUnit.SECONDS) .subscribe { Log.i("SUBSCRIBED ON:", Thread.currentThread().name) // some code }

and this is the log that gets printed:

I/MAPPING ON:: main I/SUBSCRIBED ON:: RxComputationThreadPool-1

Why is map operator being called on main thread? Shouldn't the map operator and subscribe function be called on IO thread? Where is Computation thread coming from?

And, if I add observeOn(Schedulers.io()) just below subscribeOn():

I/MAPPING ON:: RxCachedThreadScheduler-3 I/SUBSCRIBED ON:: RxComputationThreadPool-1

now map operator gets called on IO thread but subscribe is still getting called on Computation thread.

I would happily move this question to SO if it is just my misunderstanding and not an issue.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ReactiveX/RxAndroid/issues/392, or mute the thread https://github.com/notifications/unsubscribe-auth/AA7B3K_Wtid9yY4OVCM-hduwA5815Bp0ks5sao-6gaJpZM4O-RZG .

SarthakM9 commented 7 years ago

@artem-zinnatullin thanks for your time!

I am not doing any UI related operation inside map or inside subscribe. I would like to run both of them on IO thread as I am performing network operation in both. So, If I understand it right, I should do it like this:

RxTextView.afterTextChangeEvents(editText)
        .observeOn(Schedulers.io())
        .skip(1)
        .map()
        .debounce(2, TimeUnit.SECONDS)
        .observeOn(Schedulers.io())
        .subscribe {
            // whatever
        }

is this implementation correct?

JakeWharton commented 7 years ago

Pass the scheduler on which you want notifications in the subscribe lambda as the third argument to debouce. By default it's Schedulers.computation().

JakeWharton commented 7 years ago

Closing since this isn't an RxAndroid or RxJava issue but a usage question. Please consider using StackOverflow or the RxJava mailing list for questions in the future.

SarthakM9 commented 7 years ago

@JakeWharton Yes, will use SO. Thanks! :)