The Role of the ViewModel
In the Android Architecture Components, the ViewModel's primary job is to store and manage UI-related data. Its unique power lies in its Lifecycle Awareness: it remains in memory during an Activity's destruction and recreation (e.g., rotation) and only clears itself when the Activity is actually finished. For an Engineering Manager, this is the key to 'Separation of Concerns'—keeping the Activity focused on rendering while the ViewModel handles the data logic.
- ViewModel vs. Activity State
When an Activity is recreated, its local variables are wiped. To prevent Revochamp from restarting an AI generation process every time the user tilts their phone, we shift the 'Generation Status' into the ViewModel. In 2026, we utilize Kotlin Coroutines inside the viewModelScope to ensure that background tasks are automatically canceled if the user leaves the app entirely.
- ViewModel with SavedStateHandle
While ViewModels survive rotation, they do not survive Process Death (when the OS kills the app in the background to save RAM). To handle this, we use SavedStateHandle. This is a key-value map that persists through process death, allowing the user to return to their work in Chennai's humid outdoor conditions even if their mid-range device cleared the app from memory.
- The Shared ViewModel Pattern
Fragments within the same Activity can share a single ViewModel. This is a common pattern for 'Master-Detail' views in Revochamp, where one fragment updates a value and another fragment observes that change instantly, without the need for complex interface callbacks.
State Management Comparison
| Feature | Android ViewModel | Flutter Riverpod (Notifier) |
|---|---|---|
| Persistence | Survives Rotation | Survives Widget Rebuilds |
| Lifecycle Aware | Yes (Cleared on Finish) | Manual (ref.onDispose) |
| Scope | Activity/Fragment Scope | Global or Widget Scope |
| Concurrency | viewModelScope (Coroutines) | Async/Await |
| Process Death | SavedStateHandle | Hydrated Bloc / Manual Save |
| UI Binding | LiveData / StateFlow | ref.watch() / Consumer |