Mahmoud Elsakka
Mahmoud Elsakka

Reputation: 47

Why use subscribeOn in every Observable method in RxJava

I found this when trying to understand RxJava in this example

getUserObservable method which emit some users i need to know why he put .subscribeOn(Schedulers.io()) while he already call it on main funcion i provided snipt for both methods i know that subscribeOn will make the process happened on background thread , but when he called it two times is this will made any different i don't know , as i understand just calling it one time in getUsersObservable will be enough

private Observable<User> getUsersObservable() {
    String[] maleUsers = new String[]{"Mark", "John", "Trump", "Obama"};

    final List<User> users = new ArrayList<>();

    for (String name : maleUsers) {
        User user = new User();
        user.setName(name);
        user.setGender("male");

        users.add(user);
    }

    return Observable
            .create(new ObservableOnSubscribe<User>() {
                @Override
                public void subscribe(ObservableEmitter<User> emitter) throws Exception {
                    for (User user : users) {
                        if (!emitter.isDisposed()) {
                            emitter.onNext(user);
                        }
                    }

                    if (!emitter.isDisposed()) {
                        emitter.onComplete();
                    }
                }
            }).subscribeOn(Schedulers.io());
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map_operator);

    getUsersObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .map(new Function<User, User>() {
                @Override
                public User apply(User user) throws Exception {
                    // modifying user object by adding email address
                    // turning user name to uppercase
                    user.setEmail(String.format("%[email protected]", user.getName()));
                    user.setName(user.getName().toUpperCase());
                    return user;
                }
            })
            .subscribe(new Observer<User>() {
                @Override
                public void onSubscribe(Disposable d) {
                    disposable = d;
                }

                @Override
                public void onNext(User user) {
                    Log.e(TAG, "onNext: " + user.getName() + ", " + user.getGender() + ", " + user.getAddress().getAddress());
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "onError: " + e.getMessage());
                }

                @Override
                public void onComplete() {
                    Log.e(TAG, "All users emitted!");
                }
            });
}

Upvotes: 0

Views: 347

Answers (1)

Ridcully
Ridcully

Reputation: 23665

This is normally done for 2 reasons:

  • You see at the place, where the method is invoked, on which scheduler the observable is is subscribed on (if this is done within the method you do not know from outside).
  • You have the possibility to use the same method and subscribe to it on different schedulers in different places of your app.

But if you know for sure, it's always going to be the same scheduler, you can as well move the subscribeOn() into the method itself.

EDIT

I didn't see, that .subscribeOn(Schedulers.io()) is already called inside the getUsersObservable() method. It does not make sense to call it inside the method and outside, when calling the method. That seems like a bug to me. As described, above, usually .subscribeOn() is called outside the method, but you can also do it inside. Doing both makes no sense.

Upvotes: 1

Related Questions