Maksim Dmitriev
Maksim Dmitriev

Reputation: 6209

Observable.just vs Single in RxJava

I'm new to RxJava and RxAndroid and trying to understand the difference between Observable.just and Single. It looks like each is designed to emit one item for its observer.

Here is the code of my simple Android activity with two buttons. The first button creates an Observable, and the second button creates a Single:

findViewById(R.id.just).setOnClickListener(view -> Observable.just("item").subscribe(
        new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(LOG_TAG, "just onSubscribe");
            }

            @Override
            public void onNext(String s) {
                Log.d(LOG_TAG, "just s=" + s);
            }

            @Override
            public void onError(Throwable e) {
                Log.e(LOG_TAG, "just e=" + e);
            }

            @Override
            public void onComplete() {
                Log.d(LOG_TAG, "just onComplete");
            }
        }));

findViewById(R.id.single).setOnClickListener(
        view -> Single.create((SingleOnSubscribe<String>) e -> {
        })
                .subscribe(new SingleObserver<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(LOG_TAG, "single onSubscribe");
                    }

                    @Override
                    public void onSuccess(String o) {
                        Log.d(LOG_TAG, "single onSuccess");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(LOG_TAG, "single onError", e);
                    }
                }));

When I press the "Just" button, onSubscribe, onNext, and onComplete are called.

When I press the "Single" button, only SingleObserver#onSubscibe is called, and SingleObserver#onSuccess is not.

The versions of RxJava and RxAndroid in my build.gradle:

compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
// Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features.
compile 'io.reactivex.rxjava2:rxjava:2.1.3'

Upvotes: 11

Views: 8327

Answers (1)

Raghunandan
Raghunandan

Reputation: 133560

Your code is working as expected. With the first you emit item but not in the second.

You need to change to

 findViewById(R.id.single).setOnClickListener(
    view -> Single.create((SingleOnSubscribe<String>) e -> {
            if(!e.isDisposed())
            e.onSuccess("item");
    })
            .subscribe(new SingleObserver<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.d(LOG_TAG, "single onSubscribe");
                }

                @Override
                public void onSuccess(String o) {
                    Log.d(LOG_TAG, "single onSuccess" + " "+o);
                }

                @Override
                public void onError(Throwable e) {
                    Log.d(LOG_TAG, "single onError", e);
                }
            }));

Now you should see "item" in onSuccess.

Say you want to do some operation then return a string you would do as suggested above. Suppose your operation fails you can then do e.onError(new IOException());) , now you should see the error in onError

Upvotes: 3

Related Questions