RxJava2中Observable与Observer的行为及订阅相关疑问
Great question—this is one of those RxJava2 nuances that catches a lot of developers off guard, especially if you’re coming from RxJava1 or just getting started with reactive programming. Let’s break this down clearly:
Why subscribe() Returns void for Observer but Disposable for Other Params
This design choice boils down to how RxJava2 handles subscription lifecycle management:
- When you pass an
Observertosubscribe(), the framework assumes you want full control over the subscription. TheDisposableis delivered directly to your Observer via theonSubscribe(Disposable)callback, so there’s no need to return it again—hence thevoidreturn type. You’re expected to save that Disposable if you need to cancel the subscription later. - For the simplified
subscribe()overloads (likesubscribe(Consumer<T>)orsubscribe(Consumer<T>, Consumer<Throwable>)), these are meant for quick, common use cases where you don’t want to implement a full Observer. Since there’s noonSubscribecallback exposed here, RxJava2 hands you theDisposabledirectly as a return value, so you can manage cancellation without writing extra boilerplate.
This split ties back to RxJava2’s dual goals: aligning with the Reactive-Streams spec (which Flowable strictly follows) while keeping Observable flexible for non-backpressure scenarios and backward compatibility.
Does onSubscribe(Disposable) Ever Not Get Called for Observable?
Your reference to the ReactiveX Observable contract might be leftover from older reactive implementations, but in RxJava2, the rules are clear:
- For
Observable.subscribe(Observer),onSubscribeis guaranteed to be called before any other events (onNext,onComplete,onError). This holds even for edge cases like an empty Observable (which sendsonCompleteright afteronSubscribe) or an error-producing Observable (which sendsonErrorafteronSubscribe). - The only time
onSubscribemight not finish executing is if your Observer throws an uncaught RuntimeException inside theonSubscribemethod itself. But that’s a code error, not a violation of the subscription contract—RxJava2 will route that exception to the global error handler, butonSubscribewas still invoked.
As you noted, Flowable takes this a step further: since it’s strictly compliant with Reactive-Streams, the spec mandates that onSubscribe must be called exactly once for every valid subscription, before any other signals. There are no exceptions to this rule for Flowable.
Quick Cheat Sheet
- Use
subscribe(Observer)when you need full lifecycle control (remember to store the Disposable fromonSubscribe). - Use simplified
subscribe()overloads for quick event handling—they hand you the Disposable directly. - Both Observable and Flowable will always call
onSubscribefor valid subscriptions (Flowable enforces this via Reactive-Streams, Observable via its own contract).
内容的提问来源于stack exchange,提问作者Robert Lewis

