An Android template project following a multi module approach with clean architecture. It has been built following Clean Architecture Principle, Repository Pattern, MVVM Architecture in the presentation layer as well as jetpack components.
I created this repository to demonstrate best development practices by utilizing up to date tech-stack.
- Operating System : Android
- Programming Language: Kotlin
- Architecture : MVVM and Data Binding
- Dependency Injection : Hilt
- Fragment Management : Navigation Component
- Design : Material Design 3
- Android Studio : Arctic Fox | 2020.3.1 3.1 or higher
- Android Emulator or Physical android device
Complex architectures like the pure clean architecture can also increase code complexity since decoupling your code also means creating lots of data transformations(mappers) and models,that may end up increasing the learning curve of your code to a point where it would be better to use a simpler architecture like MVVM.
When using dynamic delivery you’ll need a PlayStore Developer Account in order to test the dynamic delivery feature However, there is a work around by using GloballyDynamic which provides the same dynamic delivery capabilities as PlayStore with other added advantages well suited for testing. Read More.
Dynamic feature modules require use of Android App Bundles which at the moment are not supported by all app distribution platforms and the platforms that support app bundles have different integrations. However, this can be solved by using GloballyDynamic.
So let’s get started …
Dynamic Feature Modules and Dynamic Delivery?
Dynamic feature modules allow separation of certain features and resources from the base module of the app and include them in the app bundle. User can then download and install these modules later when they are required(on demand) even after the app has already been installed.
Dynamic Delivery is Google Play’s app serving model that uses Android App Bundles to generate and server optimized APKs for each user’s device configuration so that users download only the feature and resources the need to run the app.
Play Feature Delivery allow certain features of the app to be delivered conditionally (depending on user’s language, location/country, paying or free user etc.) or downloaded on demand.
What is Clean Architecture?
A well planned architecture is extremely important for an app to scale and all architectures have one common goal- to manage complexity of your app. This isn’t something to be worried about in smaller apps however it may prove very useful when working on apps with longer development lifecycle and a bigger team.
Clean architecture was proposed by Robert C. Martin in 2012 in the Clean Code Blog and it follow the SOLID principle.
The circles represent different layers of your app. Note that:
The center circle is the most abstract, and the outer circle is the most concrete. This is called the Abstraction Principle. The Abstraction Principle specifies that inner circles should contain business logic, and outer circles should contain implementation details.
Another principle of Clean Architecture is the Dependency Inversion. This rule specifies that each circle can depend only on the nearest inward circle ie. low-level modules do not depend on high-level modules but the other way around.
Why Clean Architecture?
- Loose coupling between the code – The code can easily be modified without affecting any or a large part of the app’s codebase.
- Easier to test code.
- Separation of Concern – Different modules have specific responsibilities making it easier for modification and maintenance.
Single Responsibility: Each software component should have only one reason to change – one responsibility.
Open-Closed: You should be able to extend the behavior of a component, without breaking its usage, or modifying its extensions.
Liskov Substitution: If you have a class of one type, and any subclasses of that class, you should be able to represent the base class usage with the subclass, without breaking the app.
Interface Segregation: It’s better to have many smaller interfaces than a large one, to prevent the class from implementing the methods that it doesn’t need.
Dependency Inversion: Components should depend on abstractions rather than concrete implementations. Also higher level modules shouldn’t depend on lower level modules.
- GitHub Actions – GitHub actions is used in this project to check for syntax correctness using KtLint, execute the unit tests and generate a new package when pushing changes to the main branch.
- KtLint – The project uses KtLint to check for syntax correctness.
- Detekt – The project uses Detekt for Kotlin Static Analysis.
This project is designed to be a barebone template for new apps. This project will continuously receive updates to improve overall codebase and other libraries and techniques to keep it up to date.
This project is released under the MIT license. See LICENSE for details.
MIT License Copyright (c) 2022 Mbuodile Obiosio Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.