Reactive architectures organize apps around a clear data flow: data changes are captured, processed, and rendered. The core idea is a single source of truth that lives in a store (or repository) and is accessed through a model that exposes RxJava observables. The view renders, the view model orchestrates reactive chains, and the model/store owns state and updates. This separation decouples responsibilities, keeps reactive chains focused on transforming or fetching data, and makes the app predictable and scalable as every consumer subscribes to the same authoritative streams.
On Android, this approach is applied by extracting state and related computations into a model and letting the view model mediate between UI events and model streams. In the file browser example, the selected folder and its file list move from the view model into a FileBrowserModel that exposes observables and accepts updates. The view model updates the model in response to user actions and subscribes to the model to render results, enabling reuse, simpler testing, and clearer ownership of state. Key rules follow: the model is the only source of truth, it should deliver the latest value immediately to new subscribers, and all consumers must be prepared to handle subsequent updates.
Persisting app state builds naturally on this structure by identifying atomic state (data that cannot be derived) and storing it via a lightweight store. A minimal pattern combines a BehaviorSubject with SharedPreferences to persist and replay values; the model can swap in heavier stores later without changing its public API. For finer control, an explicit cache with a PublishSubject can be used to separate “last value” storage from update streams. The resulting architecture keeps derived state in the view/view model, durable state in stores, and the model as the reactive gateway that publishes updates, ensuring consistency, resilience, and maintainability.
FAQ
What does a reactive architecture look like at a high level?
Data changes in a store, reactive chains process those changes, and the view renders results. Updates flow into the store (from user input, network, disk), and all consumers react to store changes rather than holding their own copies.Is the “database” in this chapter a real SQL database?
No. “Database” is used as a generic term for a place where data lives. In reactive apps it’s commonly called a store or repository. It may be in-memory, backed by SharedPreferences, SQLite, ContentProviders, Firebase, or a combination. A model can use several stores.How do Model, ViewModel, and View relate in MVVM here?
- Model: the data layer that owns stores and exposes observables for reading and updating state.- ViewModel: reactive logic that transforms model data for presentation and forwards user intents back to the model; it doesn’t own state.
- View: renders UI and forwards user input. The reactive chain is separated from both store and view.
Why insist on a single source of truth? Aren’t singletons bad?
A single authoritative place prevents divergence and stale data. Conceptually a singleton-like store provides one reference (like a single URL for a server). While global singletons can be harmful, a store accessed through one reference is beneficial here. Clients must handle updates so all parts stay in sync.How does the model resemble a web server?
Like a web server, the model exposes an API to entities (for example, getVideo(id), getVideos()). The same “endpoint” can yield different data over time as state updates. Internally, the model talks to a store; externally, clients subscribe to observables and receive the latest value plus future updates.How do clients retrieve data from the model?
They request an observable and subscribe. The model should emit the latest cached value first and then push updates. BehaviorSubject or an explicit cache plus startWith are common patterns to serve the current value immediately.Where should the model be created and who owns it on Android?
Create it in an owner with an appropriate lifecycle (for example, an Activity in simple apps, or a DI container). Don’t construct it inside a ViewModel—the ViewModel consumes the model. The owner wires the ViewModel to the model.What belongs in the model vs the ViewModel? What is atomic state?
- Model: shared, authoritative state and low-level data interactions; it exposes observables and accepts updates.- ViewModel: presentation logic and transformations for the view.
- Atomic state: the minimal state that cannot be derived from anything else (for example, selectedFolder). Derived state (like the folder’s file list) is recomputed from atomic state.
BehaviorSubject or PublishSubject for model state?
- BehaviorSubject: caches the latest value and emits it immediately to new subscribers—great for “latest value first.”- PublishSubject: emits only future values; pair it with an explicit cached value and startWith to provide an initial emission. Be mindful of late subscribers and thread safety when managing the cache manually.
RxJava for Android Developers ebook for free