A comprehensive research project comparing 5 Android architecture patterns implemented with Jetpack Compose using Clean Architecture principles and the API/Impl separation technique. The project includes performance benchmarks, static code analysis, and architectural evaluations. Data is primarily served from mock JSON files, with only images being fetched from API endpoints.
This project implements the same three features (Cart, Chat, Product List) using 5 different Android architecture patterns:
- Classic MVVM (ViewModel + StateFlow)
- MVC (Model-View-Controller)
- MVP (Model-View-Presenter)
- Single-State MVVM (Custom State Pattern)
- MVI (Model-View-Intent)
Each implementation features nearly identical UI and business logic, allowing for fair performance and code quality comparisons. The project follows Clean Architecture principles with clear separation between domain, data, and presentation layers. The API/Impl separation technique is used throughout, allowing for easy swapping between implementations (e.g., mock vs. real implementations).
- Mock Data: All business data (products, cart items, chat messages, user profiles) are served from local JSON files located in the
src/mock/resources/directories of each feature module. - API Data: Only images are fetched from remote API endpoints. All other data is mock-based to ensure consistent benchmarking conditions.
The project uses a modular Clean Architecture with clear separation of concerns, implementing the API/Impl pattern for all core and feature modules:
BaseArchitecture/
├── core/ # Shared core modules
│ ├── designsystem/ # UI components & theme
│ ├── model/ # Data models
│ ├── navigation/ # Navigation setup
│ ├── ui-api/ # UI interfaces
│ ├── ui-impl/ # UI implementations
│ ├── network-api/ # Network interfaces
│ ├── network-impl/ # Network implementations
│ ├── analytics-api/ # Analytics interfaces
│ ├── analytics-impl/ # Analytics implementations
│ ├── database-api/ # Database interfaces
│ ├── database-impl/ # Database implementations
│ ├── datastore-api/ # DataStore interfaces
│ ├── datastore-impl/ # DataStore implementations
│ ├── notification-api/ # Notification interfaces
│ └── notification-impl/ # Notification implementations
│
├── feature/ # Feature modules
│ ├── cart-impl/ # Default Cart (Single-State MVVM)
│ ├── cart-impl-classicmvvm/ # Classic MVVM Cart
│ ├── cart-impl-mvc/ # MVC Cart
│ ├── cart-impl-mvp/ # MVP Cart
│ ├── cart-impl-mvi/ # MVI Cart
│ │
│ ├── product-impl/ # Default Product (Single-State MVVM)
│ ├── product-impl-classicmvvm/ # Classic MVVM Product
│ ├── product-impl-mvc/ # MVC Product
│ ├── product-impl-mvp/ # MVP Product
│ └── product-impl-mvi/ # MVI Product
│ │
│ ├── chat-impl/ # Default Chat (Single-State MVVM)
│ ├── chat-impl-classicmvvm/ # Classic MVVM Chat
│ ├── chat-impl-mvc/ # MVC Chat
│ ├── chat-impl-mvp/ # MVP Chat
│ └── chat-impl-mvi/ # MVI Chat
│
└── benchmark/ # MacroBenchmark tests
- Language: Kotlin 2.1.10
- UI Framework: Jetpack Compose
- Architecture: 5 patterns (MVVM, MVC, MVP, Single-State MVVM, MVI)
- Dependency Injection: Hilt
- Async: Kotlin Coroutines + Flow
- Build: Gradle 8.x with Version Catalog
- Min SDK: 21
- Target SDK: 36
- Java Version: 11
Shopping cart management with:
- Add/remove items
- Quantity updates
- Multi-step checkout flow
- Address selection
- Payment method selection
Real-time messaging with:
- Chat list with latest messages
- Chat detail with message history
- Real-time message streaming
- Send/receive messages
E-commerce product browsing with:
- Product list with grid view
- Category filtering
- Pagination
- Product details
- Android Studio Hedgehog (2024.1.1) or later
- JDK 11 or higher
- Android SDK 36
- Gradle 8.x
Important: Only one architecture pattern can be active at a time. To test a specific architecture, you must configure the app/build.gradle.kts file.
You can configure the architecture in two ways:
In app/build.gradle.kts, locate the dependency section and configure it as follows. Uncomment only the architecture you want to test for each feature (Product, Cart, Chat), and keep the other 4 architectures commented out:
// Product - Select ONE architecture
//implementation(projects.feature.productImpl) // Single-State MVVM
//implementation(projects.feature.productImplMvp) // MVP
//implementation(projects.feature.productImplMvc) // MVC
//implementation(projects.feature.productImplClassicmvvm) // Classic MVVM
//implementation(projects.feature.productImplMvi) // MVI
// Cart - Select ONE architecture
//implementation(projects.feature.cartImpl) // Single-State MVVM
//implementation(projects.feature.cartImplMvp) // MVP
//implementation(projects.feature.cartImplMvc) // MVC
//implementation(projects.feature.cartImplClassicmvvm) // Classic MVVM
//implementation(projects.feature.cartImplMvi) // MVI
// Chat - Select ONE architecture
//implementation(projects.feature.chatImpl) // Single-State MVVM
//implementation(projects.feature.chatImplMvp) // MVP
//implementation(projects.feature.chatImplMvc) // MVC
//implementation(projects.feature.chatImplClassicmvvm) // Classic MVVM
//implementation(projects.feature.chatImplMvi) // MVIExample: To test MVP architecture, uncomment all *Mvp implementations and keep others commented.
Use the provided automation script to automatically configure and run benchmarks across all architectures. The script handles:
- Automatic BuildConfig updates in both
appandbenchmarkmodules - Automatic dependency management in
app/build.gradle.kts - State management to resume from failures
- Connection monitoring for WiFi ADB (energy mode)
Benchmark Modes:
- General Mode (default): Runs
BenchmarkTestSuitewith all benchmarks (Startup, Rendering, Interaction, Memory). Works with USB or WiFi ADB connection. - Energy Mode (
--energy): Runs onlyEnergyBenchmarktests for power consumption measurement. Requires WiFi ADB connection and device must be unplugged.
Usage Examples:
# Run all architectures in general mode (BenchmarkTestSuite)
./scripts/run_benchmarks.sh
# Run all architectures in energy mode (EnergyBenchmark only)
./scripts/run_benchmarks.sh --energy
# Run single architecture in general mode
./scripts/run_benchmarks.sh -a mvi
# Run single architecture in energy mode
./scripts/run_benchmarks.sh --energy -a mvi
# Clean start (delete previous results and state)
./scripts/run_benchmarks.sh -c
# Clean start with energy mode
./scripts/run_benchmarks.sh --energy -cScript Features:
- Automatically iterates through all 5 architectures (classicmvvm, singlestatemvvm, mvc, mvp, mvi)
- Updates BuildConfig and dependencies for each architecture
- Builds and runs benchmarks with retry logic (up to 3 retries)
- Includes cooldown periods: 2 minutes between retries, 5 minutes between architectures
- Manages state to resume from failures
- Monitors ADB connection (WiFi ADB monitoring for energy mode only)
For detailed script documentation, see scripts/README.md.
# Clone the repository
git clone https://github.com/yfy/android-architecture-benchmarks
# Build the project
./gradlew assembleDebug
# Run benchmarks (see Benchmark section below)
./gradlew :benchmark:connectedCheckBenchmarks are configured to run using BenchmarkTestSuite class. All modules must use the mockRelease build variant for accurate benchmarking.
The easiest way to run benchmarks across all architectures is using the automation script:
# General mode - runs BenchmarkTestSuite (all benchmarks)
./scripts/run_benchmarks.sh
# Energy mode - runs only EnergyBenchmark (requires WiFi ADB, device unplugged)
./scripts/run_benchmarks.sh --energyThe script automatically handles architecture configuration, building, and running benchmarks. See Architecture Configuration section above for more details.
If you prefer to run benchmarks manually:
- Select Architecture: Configure
app/build.gradle.ktsas described in the Architecture Configuration section - Select Build Variant: Ensure
mockReleaseis selected for all modules (especially theappmodule) - Run Benchmarks: Execute
BenchmarkTestSuiteusing Android Studio's test runner or via Gradle:
# Run all benchmarks
./gradlew :benchmark:connectedCheck
# Or run specific benchmark test
./gradlew :benchmark:connectedCheck --tests "BenchmarkTestSuite"Note: Make sure your device or emulator is connected and unlocked before running benchmarks.
# Run Detekt
./gradlew detekt
# Run Lint
./gradlew lint
# SonarQube analysis (requires local SonarQube server configuration)
# Configure SonarQube in sonar-project.properties and run:
# ./gradlew sonarRaw benchmark data is organized into two categories:
Contains unprocessed raw benchmark results in JSON format for each architecture:
classicmvvm_result.jsonmvc_result.jsonmvp_result.jsonmvi_result.jsonsinglestatemvvm_result.jsonruns_detail.json- Detailed runs data extracted from raw benchmark result files
Contains raw energy consumption measurements for each architecture:
- Architecture-specific folders (e.g.,
mvc/,mvi/,mvp/, etc.) - Detailed CSV files per scenario (Chat_Streaming, Shopping_Cart, Product_Browsing)
- Energy consumption summary files (CSV and JSON)
- README files with test metadata
Processed and consolidated results are organized into two categories:
Contains processed performance benchmark data:
benchmarks.csv- Performance benchmark metrics for all architecturesmemory.csv- Memory usage metricsstatic.csv- Static code analysis metricsmemory_phases.csv- Memory usage by phasestatistical_tests.csv- Statistical comparison tests between architectures
Contains normalized energy consumption data:
normalized_energy_data.csv- All normalized energy measurements (60-second baseline)normalized_energy_statistics.csv- Statistical summary per architecture-scenario
This is a research project for thesis purposes. Contributions and feedback are welcome through issues or pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.
Yusuf Furkan Yılmaz - Master Thesis Research Project
Note: This project is part of a university thesis research project on Android architecture patterns and their impact on code quality and performance.