This chapter recasts Android networking as reactive event streams to tame callback-heavy code. It introduces building the network layer with RxJava and Retrofit, emphasizing the decoupling of data sources from subscribers and the benefits of composing asynchronous flows. You learn the core roles of observables and subscribers, thread switching with observeOn for UI updates, and the RxJava 2 family of types (Observable, Single, Maybe, Completable, Flowable) and when to use them in typical app scenarios.
The chapter models a network request as an observable that emits a single item and completes, then extends this into a practical example: an RSS/Atom reader that aggregates multiple feeds. Each feed becomes an Observable>; combineLatest merges their latest emissions into one stream, after which map transforms the data (for example, sorting by date) before rendering. Along the way, it demonstrates building clear, one-step-at-a-time processing chains, converting between observable types when needed, and ensuring UI work happens on the main thread.
Robustness and scalability are addressed through immutability and error handling. The chapter explains why you should avoid mutating items flowing through streams (to support multiple subscribers safely), advocating copy-on-write patterns and builders for producing new instances. Errors are treated as notifications: you can retry transient failures with retry and gracefully degrade with onErrorReturn (for example, emitting an empty list when a feed fails). Finally, it shows how the same composition scales from two to many feeds by passing a list of observables to combineLatest, yielding a flexible, resilient, and maintainable reactive networking layer.
FAQ
How do I model a network request as an observable in RxJava?You expose a function that returns an Observable (often a Single for one-shot responses) and subscribe to it. Subscribing starts the request, and when the data arrives the subscriber is called. Because callbacks likely run off the main thread, switch to the UI thread just before subscribing with observeOn(AndroidSchedulers.mainThread()). Retrofit integrates well here and can return Observable/Single directly.Which RxJava 2 type should I use for HTTP calls?- Single: best for a one-time response (value or error) typical of HTTP calls. You can convert it to Observable with toObservable(). - Maybe: for an optional single value (value or complete without value). - Completable: when you only care that something finished (no value), e.g., a side-effect. - Observable: for multiple values over time. - Flowable: for high-throughput streams with backpressure needs (usually not needed for Android UI networking).What’s the difference between Observer and Subscriber in RxJava 2?Most types (Observable, Single, Maybe, Completable) use Observer to receive emissions. Flowable is the special case that uses Subscriber because it supports backpressure. In practice, you can think of them all as “subscribers” that react to emitted items.How can I combine results from multiple network calls?Use combineLatest. It waits until each source has emitted at least one item, then emits a combined value whenever any source updates. Provide a combining function to merge the results (for example, concatenate two List<Entry>). For resilience, apply retry(n) and onErrorReturn(...) to each source before combining so one failing feed doesn’t cancel the whole result.How do I ensure UI updates happen on the main thread?Keep the network work on a background thread (Retrofit/your wrapper will do this), then switch downstream operators and subscribers to the main thread just before UI changes: observable.observeOn(AndroidSchedulers.mainThread()).subscribe(...). observeOn affects all following operations.How do I sort and transform network data with Rx?Use map to apply a pure function to each emission. For example, implement Comparable in your Entry and write a sortList(List<Entry>) that returns a new, sorted copy. Then do listObservable.map(this::sortList) and subscribe your UI to the sorted stream. Note: heavy work inside map can block the current thread.Why is immutability important in Rx chains?Because the same emitted item can flow to multiple subscribers/operators, mutating shared data causes races and unpredictable behavior. Always treat inputs as read-only and return new instances when “changing” data (copy a list before sorting, use builder patterns for objects). The extra allocations are typically a small cost on modern runtimes.How should I handle network errors with RxJava?Errors are notifications that terminate the stream. You can: 1) provide an error consumer in subscribe to log/show issues; 2) retry transient failures with retry(n) on each source; 3) recover with fallback data using onErrorReturn(e -> Collections.emptyList()) so the UI can still render partial results. Place onErrorReturn after retry so retries happen first.How do I scale from two feeds to many?Create a List<Observable<List<Entry>>>, applying retry and onErrorReturn to each. Then call combineLatest(observableList, combiner) where the combiner aggregates the emitted lists into a single list. This version doesn’t require you to know the number of feeds at compile time.When do I need Flowable and backpressure?Only when a source can outpace consumers with a very high volume of items (for example, IoT sensor streams). Typical Android UI/network scenarios work fine with Observable and its simpler buffering model; Flowable is usually overkill for these cases.
pro $24.99 per month
access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!