This is a sample project to demostrate use of various components of Android.
This project brings to table set of best practices, tools, and solutions:
- 100% Kotlin
- Modern architecture (Clean Architecture, Model-View-ViewModel, Model-View-Intent)
- Android Jetpack
- A single-activity architecture, using the Navigation component
Min API level is set to 21
, so the presented approach is suitable for over
85% of devices running Android. This project takes advantage of many
popular libraries and tools of the Android ecosystem. Most of the libraries are in the stable version unless there is a
good reason to use non-stable dependency.
-
Tech-stack
- Kotlin + Coroutines - perform background operations
- Retrofit - networking
- Glide - fast and efficient image loading library for Android
- Jetpack
- Navigation - deal with whole in-app navigation
- LiveData - notify views about database change
- Lifecycle - perform an action when lifecycle state changes
- ViewModel - store and manage UI-related data in a lifecycle conscious way
-
Architecture
- MVVM + MVI (presentation layer)
- Android Architecture components (ViewModel, LiveData, Navigation)
-
Gradle
The modularized code-base approach provides few benefits:
- better separation of concerns. Each module has a clear API., Feature related classes life 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
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
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)
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 thedata layer
(Dependency inversion).
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 thedomain
layer, not to perform any business logic (domain
layeruse case
responsibility). -
Mapper - maps
data model
todomain model
(to keepdomain
layer independent from thedata
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.
Below diagram presents application app flow when a user interacts with the application:
Read related articles to have a better understanding of underlying design decisions and various trade-offs.
- Multiple ways of defining Clean Architecture layers
- How to Develop a Secure Android App
- All about Memory Leaks in Android
- Android Navigation Architecture Component
There are a few ways to open this project.
- Android Studio -> File -> New -> From Version control -> Git
- Enter
https://github.com/amritlalsahu5/RandomDogsGenerator.git
into URL field
- Run
git clone https://github.com/amritlalsahu5/RandomDogsGenerator.git
- Android Studio -> File -> Open