Skip to content

Shouldn't AndroidSchedulers.mainThread() act as Schedulers.immediate() when already on the main thread? #335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
danielesegato opened this issue Sep 29, 2016 · 5 comments

Comments

@danielesegato
Copy link

danielesegato commented Sep 29, 2016

This is more a discussion / question then anything else.

Let's take this code as example:

@Override
public void onResume() {
    Log.i("TEST", "Before subscription");
    Observable.just("hi!")
        .subscribeOn(AndroidSchedulers.mainThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(val -> Log.i("TEST", "Received: + val));
    Log.i("TEST", "After subscription");
}

it prints:

Before subscription
After subscription
Received: hi!

If executed on the main thread, wouldn't it be useful to have a way of making it print:

Before subscription
Received: hi!
After subscription

?

I'm thinking about how Loaders works, when you init() they immediately return the value if it has already been loaded.

The recyclerView is different in this but the old ListView didn't correctly resumed the list if you didn't set your data in the onCreated method of the Activity (if I recall correctly). I remember it resetting to the top.

I wouldn't change the current behavior for backward compatibility, but I'd add a new schedulers working like that if possible.

What do you think? Would it be useful?

@akarnokd
Copy link
Member

This comes up often with GUI-type schedulers. The problem is with the recursive scheduling aspects of many flows is that they can pin the GUI thread processing one particular sequence and not executing GUI update requests from other sources. By doing this one by one, there is a much higher chance of mixing various actions and keeping the GUI responsive.

Besides, doing to much workload on the GUI thread is usually considered a bad thing. What you are suggesting is how Schedulers.from() works now and someone wanted to change to this GUI style here.

Each library can decide what's the reasonable to do and since RxJava is not a framework, you are free to implement your own scheduler (even by copying and modifying an existing one to your needs). Schedulers are one of the things that can live anywhere (unlike instance methods on Observable).

@JakeWharton
Copy link
Contributor

Prior art: #228, JakeWharton/RxBinding#28.

If you want something to run synchronously the answer is not schedule and ensure you're already on the main thread. If you are doing something like observeOn(mainThread()) but you don't know what thread the stream is on then that's the thing you need to fix.

Also more info here: https://www.youtube.com/watch?v=va1d4MqLUGY

@PaulWoitaschek
Copy link
Contributor

Im still heavily struggling with this aspect of RxJava.

I have a manager class that returns data. It returns it from cache if available, else from network.
My clients now need to apply observeOn so the network requests don't run on the UI thread.
However this leads to the UI flashing when my ProgressBar displays for the fraction of a second when the data comes from cache.
How can I handle that?

@hyysgit
Copy link

hyysgit commented Jan 27, 2019

可以这样写:.subscribeOn(Schedulers.io()) .observeOn(Schedulers.from(new Executor(){ @Override public void execute(@android.support.annotation.NonNull Runnable command) { runOnUiThread(command); } }))

@hyysgit
Copy link

hyysgit commented Jan 27, 2019

或者创建一个类
`package com.yongge.retrofit_test.utils;

import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;

import java.util.concurrent.Executor;

import rx.Scheduler;
import rx.schedulers.Schedulers;

/**

  • Created by 勇哥.

  • Email: [email protected]

  • 2019-01-27
    */
    public class AndroidSchedulers implements Executor {

    private static AndroidSchedulers instance;

    private final Scheduler mMainScheduler;
    private final Handler mHandler;

    private AndroidSchedulers() {
    mHandler = new Handler(Looper.myLooper());
    mMainScheduler = Schedulers.from(this);
    }

    public static synchronized Scheduler mainThread() {
    if (instance == null) {
    instance = new AndroidSchedulers();
    }
    return instance.mMainScheduler;
    }

    @OverRide
    public void execute(@nonnull Runnable command) {
    mHandler.post(command);
    }

}

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants