An Android sample project exploring Clean Architecture with Kotlin, MVVM, Hilt, Retrofit, Room, and Coroutines.
CleanArchitectureTest is an Android project created to explore how Clean Architecture concepts can be applied to a practical Android application.
The project separates responsibilities across data, domain, and presentation layers while combining common Android technologies such as Retrofit, Room, Hilt, Coroutines, ViewModel, and LiveData.
The main goal of the project is to experiment with a maintainable application structure where remote APIs, local storage, business logic, and UI state are clearly separated.
The project is organized around three primary areas:
data
├── local
│ ├── image
│ └── todo
│
└── remote
├── image
└── todo
domain
├── model
├── repository
└── usecase
presenter
├── base
├── common
├── di
├── extension
├── util
└── view
The general data flow follows:
Remote API / Local Database
↓
Data Source
↓
Repository
↓
UseCase
↓
ViewModel
↓
UI
This structure keeps data access, application logic, and presentation responsibilities separated.
- Clean Architecture-inspired project structure
- MVVM-based presentation layer
- Dependency injection with Hilt
- REST API communication with Retrofit and OkHttp
- Local persistence with Room
- Asynchronous operations using Kotlin Coroutines
- UI state management with ViewModel and LiveData
- Separate local and remote data sources
- Repository abstraction between data sources and domain logic
- Multiple Retrofit configurations for different APIs
- DataBinding and ViewBinding support
The data layer contains implementations for both remote and local data sources.
Retrofit and OkHttp are used for network communication.
The project configures separate Retrofit instances for different API endpoints and injects them using Hilt qualifiers.
Remote data is accessed through dedicated data source implementations before being passed through repository abstractions.
Room is used for local persistence.
Local data sources provide database access for image and Todo data while keeping database implementation details outside the presentation layer.
The domain layer contains models, repository abstractions, and use cases.
For example:
ImageRemoteRepository ─┐
├── ImageUseCase
ImageLocalRepository ──┘
ImageUseCase coordinates remote and local image operations, including:
- Loading remote image data
- Reading locally stored images
- Storing image data
- Updating local state
- Removing local data
A similar structure is used for Todo data.
The presentation layer contains Activities, Fragments, ViewModels, adapters, common UI components, and dependency injection modules.
ViewModels communicate with use cases rather than directly accessing Retrofit or Room.
For example:
ImageSelectActivity
↓
ImageSelectViewModel
↓
ImageUseCase
↓
Repository
↓
Remote / Local DataSource
This keeps UI logic separated from data access implementation.
Hilt is used to connect the different application layers.
Dedicated modules provide dependencies for:
- Network clients
- Retrofit instances
- Databases
- DAOs
- Data sources
- Repositories
- Preferences
Repository implementations are bound to their corresponding interfaces, allowing the rest of the application to depend on abstractions rather than concrete implementations.
The project uses:
- Retrofit
- OkHttp
- Gson
Multiple Retrofit instances are configured using custom Hilt qualifiers.
This allows different remote APIs to coexist while sharing common networking infrastructure such as the OkHttp client.
Room provides the local persistence layer.
The application separates Room-specific database access from the domain and presentation layers through DAO, DataSource, and Repository abstractions.
Kotlin Coroutines are used for asynchronous operations.
Network and database operations are performed away from the main thread, while ViewModels expose results to the UI through LiveData.
- Kotlin
- Android SDK
- Android Jetpack
- MVVM
- Hilt
- Retrofit
- OkHttp
- Room
- Kotlin Coroutines
- ViewModel
- LiveData
- DataBinding
- ViewBinding
- RecyclerView
- ViewPager2
This project was created as a practical experiment in structuring an Android application around Clean Architecture concepts.
Rather than focusing on a single application feature, the project explores how common Android components can be separated into clear responsibilities and connected through dependency injection.
It serves as a reference for organizing network communication, local persistence, domain logic, and presentation state within an Android application.
This repository is an experimental architecture project and technical reference.
It reflects the Android development stack and architectural approaches explored at the time of its development.
Beomjin Kim
Android Developer specializing in Kotlin and mobile development.
Portfolio: https://happyhouse.dev