A lightweight Android application demonstrating clean architecture principles using the MVVM (Model-View-ViewModel) design pattern. The app displays a dynamic list of orders, handles background data generation, and showcases advanced architecture concepts.
This project is built strictly around the MVVM Architecture to ensure separation of concerns, testability, and lifecycle awareness.
┌──────────────────────────────┐
│ View │
│ (Activity / Fragment) │
└──────────────┬───────────────┘
│ Observes (LiveData)
▼
┌──────────────────────────────┐
│ ViewModel │
└──────────────┬───────────────┘
│ Requests Data
▼
┌──────────────────────────────┐
│ Repository │
└──────────────────────────────┘
- View: Responsible for displaying data and capturing user interactions. It holds no references to the ViewModel's underlying data logic directly, decoupling it from the Android system's lifecycle.
- ViewModel: Acts as a bridge between the View and the Data layer. It retains its state during configuration changes (like screen rotations) and remains in memory until the host Activity or Fragment is completely destroyed (
onCleared()). - LiveData / MutableLiveData: Used to implement the Observer pattern.
MutableLiveDatais encapsulated inside the ViewModel to allow data updates.- Exposed to the View as read-only
LiveDatato prevent the UI from accidentally modifying the state.
- Lifecycle Awareness: By utilizing
LiveData, the UI automatically updates to match the current data state. It eliminates common issues like memory leaks and crashes caused by stopped Activities. - Multi-View Data Sharing: Multiple fragments can attach to a single, shared ViewModel. This acts as a centralized repository, allowing seamless data sharing across different UI components.
- Asynchronous Processing: Powered by Kotlin Coroutines to shift heavy data generation tasks off the main thread, keeping the UI smooth and responsive.
- Thread Safety: Utilizes
postValue()on background threads to safely dispatch data updates back to the main thread. - Unit Test-Ready: Because the ViewModel contains no Android UI framework dependencies, it can be easily isolated for quick, reliable Unit Testing.
To prevent severe memory leaks, the ViewModel never references an Activity Context. If an Activity is destroyed and recreated during a configuration change, any reference held by a long-lived ViewModel would clog the memory heap.
- When a context is strictly required, the application utilizes the Application Context, which persists across the entire app lifecycle and is entirely safe from leaks.
The application showcases advanced data streaming techniques, including:
- Transformations: Transforming emitted LiveData values on the fly before they reach the View.
- MediatorLiveData: Merging and managing multiple data sources into a single observable stream.
The diagram below illustrates how the ViewModel survives configuration changes, allowing the View to seamlessly reconnect and retrieve active data operations exactly where it left off.
A detailed breakdown of how data flows from our background threads up to the user interface:
- Language: Kotlin
- Architecture: MVVM (Model-View-ViewModel)
- Multi-threading/Asynchronous Programming: Kotlin Coroutines
- UI Components: LiveData, Lifecycle-aware components

