CleanArchitecture is a sample project that presents a modern, 2021 approach to Android application development.

Overview

Clean Architecture

Kotlin Version AGP Gradle

CleanArchitecture is a sample project that presents a modern, 2021 approach to Android application development.

The goal of the project is to combine popular libraries/tools and demonstrate best developement practices by utilizing up to date tech-stack and presenting modern Android application Architecture that is modular, scalable, maintainable, and testable. This application may look simple, but it has all the pieces that will provide the rock-solid foundation for the larger app suitable for bigger teams and long application lifecycle.

This project is being maintained to match industry standards. Please check CONTRIBUTING page if you want to help.

Project characteristics and tech-stack

This project takes advantage of best practices, many popular libraries and tools in the Android ecosystem. Most of the libraries are in the stable version unless there is a good reason to use non-stable dependency.

Architecture

Feature related code is placed inside one of the feature modules. We can think about each feature as the equivalent of microservice or private library.

The modularized code-base approach provides few benefits:

  • better separation of concerns. Each module has a clear API., Feature related classes live in different modules and can't be referenced without explicit module dependency.
  • features can be developed in parallel eg. by different teams
  • each feature can be developed in isolation, independently from other features
  • faster compile time

Module types and module dependencies

This diagram presents dependencies between project modules (Gradle sub-projects).

module_dependencies

Note that due usage of Android dynamic-feature module dependencies are reversed (feature modules are depending on app module, not another way around).

We have three kinds of modules in the application:

  • app module - this is the main module. It contains code that wires multiple modules together (dependency injection setup, NavHostActivity, etc.) and fundamental application configuration (retrofit configuration, required permissions setup, custom application class, etc.).
  • application-specific library_x modules that some of the features could depend on. This is helpful if you want to share some assets or code only between few feature modules (currently app has no such modules)
  • feature modules - the most common type of module containing all code related to a given feature.

Feature module structure

Clean architecture is the "core architecture" of the application, so each feature module contains own set of Clean architecture layers:

module_dependencies_layers

Notice that app module and library_x modules structure differs a bit from feature module structure.

Each feature module contains non-layer components and 3 layers with distinct set of responsibilities.

feature_structure

Presentation layer

This layer is closest to what the user sees on the screen. The presentation layer is a mix of MVVM (Jetpack ViewModel used to preserve data across activity restart) and MVI (actions modify the common state of the view and then new state is edited to a view via LiveData to be rendered).

common state (for each view) approach derives from Unidirectional Data Flow and Redux principles.

Components:

  • View (Fragment) - presents data on the screen and pass user interactions to View Model. Views are hard to test, so they should be as simple as possible.
  • ViewModel - dispatches (through LiveData) state changes to the view and deals with user interactions (these view models are not simply POJO classes).
  • ViewState - common state for a single view
  • NavManager - singleton that facilitates handling all navigation events inside NavHostActivity (instead of separately, inside each view)

Domain layer

This is the core layer of the application. Notice that the domain layer is independent of any other layers. This allows to make domain models and business logic independent from other layers. In other words, changes in other layers will have no effect on domain layer eg. changing database (data layer) or screen UI (presentation layer) ideally will not result in any code change withing domain layer.

Components:

  • UseCase - contains business logic
  • DomainModel - defies the core structure of the data that will be used within the application. This is the source of truth for application data.
  • Repository interface - required to keep the domain layer independent from the data layer (Dependency inversion).

Data layer

Manages application data and exposes these data sources as repositories to the domain layer. Typical responsibilities of this layer would be to retrieve data from the internet and optionally cache this data locally.

Components:

  • Repository is exposing data to the domain layer. Depending on application structure and quality of the external APIs repository can also merge, filter, and transform the data. The intention of these operations is to create high-quality data source for the domain layer, not to perform any business logic (domain layer use case responsibility).

  • Mapper - maps data model to domain model (to keep domain layer independent from the data layer).

  • RetrofitService - defines a set of API endpoints.

  • DataModel - defines the structure of the data retrieved from the network and contains annotations, so Retrofit (Moshi) understands how to parse this network data (XML, JSON, Binary...) this data into objects.

Data flow

Below diagram presents application data flow when a user interacts with album list screen:

app_data_flow

Dependency management

This project utilizes multiple mechanics to easily share the same versions of dependencies.

App library dependencies

External dependencies (libraries) are defined using versions catalog feature in the settings.gradle file. These dynamic library versions are locked using Gradle locking dependency mechanism - concrete dependency versions are stored in MODULE_NAME/gradle.lockfile files.

To update lock files run ./gradlew test lint s --write-locks command and commit updated gradle.lockfile files to repository.

Each feature module depends on the app module, so dependencies are shared without need to add them explicitly in each feature module.

Gradle plugin dependencies

Gradle plugins are defined in pluginManagement block (settings.gradle file).

Dynamic versions aren't supported for Gradle plugins, so locking dependency mechanism can't be used (like for app library dependencies), and thus versions of some libraries & plugins have to be hardcoded in the gradle.properties file.

There is no easy way to share id between pluginManagement block and buildSrc folder, so plugin ids (also used within build scripts), have to be duplicated in the GradlePluginId file.

Shared dependencies

Gradle is missing proper built-in mechanism to share dependency versions between app library dependency and Gradle plugin dependency eg. Navigation component library uses Safe Args Gradle plugin with the same version.

To enable sharing all versions that are used for both plugins and libraries are defined in gradle.properties.

Unfortunately this technique cannot be applied to older Gradle plugins (added by classpath, not by pluginManagement), so some version in the gradle.properties are still duplicated.

CI pipeline

CI is utilizing GitHub Actions. Complete GitHub Actions config is located in the .github/workflows folder.

PR Verification

Series of workflows runs (in parallel) for every opened PR and after merging PR to main branch:

  • ./gradlew lintDebug - runs Android lint
  • ./gradlew detekt - runs detekt
  • ./gradlew ktlintCheck - runs ktlint
  • ./gradlew testDebugUnitTest - run unit tests
  • ./gradlew connectedCheck - run UI tests
  • ./gradlew :app:bundleDebug - create app bundle

Dependency updates

The update-dependencies task run periodically and creates a pull request containing dependency updates (updated gradle .lockfile files used by Gradle’s dependency locking).

Design decisions

Read related articles to have a better understanding of underlying design decisions and various trade-offs.

What this project does not cover?

The interface of the app utilizes some of the modern material design components, however, is deliberately kept simple to focus on application architecture.

Getting started

There are a few ways to open this project.

Android Studio

  1. Android Studio -> File -> New -> From Version control -> Git
  2. Enter https://github.com/ShushantTiwari-ashu/CleanArchitecture.git into URL field an press Clone button

Command-line + Android Studio

  1. Run git clone https://github.com/ShushantTiwari-ashu/CleanArchitecture.git command to clone project
  2. Open Android Studio and select File | Open... from the menu. Select cloned directory and press Open button

Inspiration

This is project is a sample, to inspire you and should handle most of the common cases, but please take a look at additional resources.

Cheat sheet

Android projects

Other high-quality projects will help you to find solutions that work for your project:

You might also like...
Clean Code and Reactive Programming PlayGround for Bangkit 2021

Clean Code and Reactive Programming PlayGround for Bangkit 2021 Hello! This repo contains the IntelliJ project that I use to present my talk, "Clean A

Android-Boilerplate - Base project for android development with new technology

Android-Boilerplate Base project for android development with new technology, in

A simple project that describes the relationship between the view and it's viewmodel in android development
A simple project that describes the relationship between the view and it's viewmodel in android development

View-ViewModel-Communication A simple project that describes the relationship between the view and it's viewmodel in android development In MVVM archi

Pleasant Android application development
Pleasant Android application development

⚠️ Anko is deprecated. Please see this page for more information. Anko is a Kotlin library which makes Android application development faster and easi

Stateful is a Kotlin library which makes Android application development faster and easier.

Stateful Stateful is a Kotlin library which makes Android application development faster and easier. It helps you delete all the boilerplate code for

AndroidappTemplate - A GitHub template repository intended to kickstart development on an Android application

Android App Template This is a GitHub template repository intended to kickstart

Rick-and-morty-app - Android mobile application development with clean architecture
Rick-and-morty-app - Android mobile application development with clean architecture

Android - Rick And Morty App MVVM architecture Dependency Injection (Dagger) Ret

Kotlin-dsl-sample - Preferences project on android

kotlin-dsl-example Sample preferences project on android. How to use val

A sample project demonstrating clean architecture in an Android app
A sample project demonstrating clean architecture in an Android app

Android Clean Architecture Sample A sample project demonstrating clean architecture in an Android app Tech stack Kotlin Coroutines Flow Jetpack App St

Owner
Shushant tiwari
👋 Hi, I’m @ShushantTiwari-ashu 👨🏻‍💻 Head of Mobile | Android Developer 🚧 Working at Mobile Programming LLC 🖥 Developing in Java, Kotlin and Flutter
Shushant tiwari
Cleanarchitecture MVVM Hilt base - Android Clean Architecture example project

Android Clean Architecture example project Note: This is project based on MVVM c

Mohsin Javed 4 Aug 30, 2022
REST countries sample app that loads information from REST countries API V3 to show an approach to using some of the best practices in Android Development.

MAJORITY assignment solution in Kotlin via MVVM Repository Pattern. REST countries sample app that loads information from REST countries API V3 to sho

Rehan Sarwar 1 Nov 8, 2022
Sample project that shows an approach for designing a multi-module architecture for Jetpack Compose Android applications.

Compose Multi-Module Architecture Sample Sample project that shows an approach for designing a multi-module architecture for Jetpack Compose Android a

Pavlo Stavytskyi 77 Jan 3, 2023
📒 NotyKT is a complete 💎Kotlin-stack (Backend + Android) 📱 application built to demonstrate the use of Modern development tools with best practices implementation🦸.

NotyKT ??️ NotyKT is the complete Kotlin-stack note taking ??️ application ?? built to demonstrate a use of Kotlin programming language in server-side

Shreyas Patil 1.4k Jan 4, 2023
🪐 Modern Android development with Hilt, Coroutines, Flow, JetPack(ViewModel) based on MVVM architecture.

Ceres ?? Modern Android development with Hilt, Coroutines, Flow, JetPack(ViewModel) based on MVVM architecture. Download Gradle Add the dependency bel

Teodor G. 21 Jan 11, 2023
ATH Sample is a sample Authentication and Authorization Application with Kotlin Language and MVVM architecture.

ATH Sample ATH Sample is a sample Authentication and Authorization Application with Kotlin Language and MVVM architecture. Overview ATH Sample is a sa

AbolfaZl RezaEi 4 Jun 8, 2021
This is a sample app to use [Molecule library] and solve some scoping problems in Android development.

Android sample app Problem It's started when P.Y. in Twitter shared this tweet and his post, which is a correct complain about introducing a new set o

Hadi 37 Oct 28, 2022
A sample project that helps to start building a Mobile Kotlin Multiplatform application

Mobile Kotlin multiplatform project template A sample project that helps to start building a Mobile Kotlin Multiplatform application. It establishes a

Dizel 0 Oct 16, 2021
WordMasterKMP - WIP Kotlin Multiplatform sample inspired by Wordle and also Word Master web sample

WordMasterKMP WIP Kotlin Multiplatform sample inspired by Wordle and also Word M

John O'Reilly 56 Oct 4, 2022
ViewModel LiveData Sample - Sample of using ViewModel, LiveData and Data Binding

ViewModel_LiveData_Sample Sample Code for Lesson 8 using ViewModel, LiveData and

null 0 Mar 18, 2022