If you want to check directly the project before continuing reading the introduction, you can do by accessing the following link:
Introduction
I built an Android Rorty Application(Rick And Morty) to reinforce what I’ve learned so far and to improve myself.
Rorty focused on the scalability, testability and maintainability written in Kotlin, following best practices using Jetpack.
“Of course, nothing is perfect, especially if it just came out. I just tried to apply what I learned to the best of my ability. 😊 ”
What Did I Develop
The project presents a modern, approach to Android application development using Kotlin and latest tech-stack.
The goal of the project is to demonstrate best practices, provide a set of guidelines, modular application, scalable, maintainable and testable. This application may look simple, but it has all of these small details that will set the rock-solid foundation of the larger app suitable for bigger teams and long application lifecycle management.
For this project I used the Clean Modular Architecture. I divided the development into two phases. The first set of MVP Features:
- Splash
- Home
- Characters
- Character Detail
- Favorites
- Settings
I developed the application up to the 1st stage but it is not finished yet. If everything is finished/previously on time, I will make a second set of features. The second set of properties would be:
- Character locations on Character Detail
- Search or Filter
- Settings add some features
Screenshots
Environment Setup
In order to be able to build the application you’ll need Android Studio Minimum version Bumblebee (2021.1.1)
Application structure
One of the key benefits of modularization architecture is supposed to be clear navigation throughout the app and source code. Looking at the root folder of the project, the following structure becomes clear.
- App module
The :app
module is a com.android.application, which is needed to create the App Bundle. It’s android specific and contains fragments, view models, adapters, activities, and so on. It also contains a service locator to manage dependencies, but you can use Hilt if you prefer. I used it.
- BuildSrc module
The :buildSrc
module is responsible for dependency management. It control and manage all dependencies in one place with Kotlin.
- Data module
The :data
module contains the implementation of the abstract definitions of the domain layer. Can be reused by any application without modifications. It contains repositories and data sources implementations, the database definition and its DAOs, the network APIs definitions, the definition of repositories, some mappers to convert network API models to database models, and vice versa.
- The
:data:model
module contains the definitions of ui model, network response and entity classes. - The
:data:local
module contains the definitions dao, database, caching operations using Room. - The
:data:remote
module contains the network operations defining API endpoints using Retrofit. - The
:data:repository
module contains the exposing data to the domain layer
- Domain module
The :domain
module contains the definitions of the business logic of the app, some mappers for use in ui, and the definition of the use cases. This is the core layer of the application. The domain
layer is independent of any other layers domain business logic can be independent from other layers.This means that changes in other layers will have no effect on domain layer eg. screen UI (presentation layer) or changing database (data layer) will not result in any code change withing domain layer.
Components of domain layer include:
usecase
: They enclose a single action, like getting data from a database or posting to a service. They use the repositories to resolve the action they are supposed to do. They usually override the operatorinvoke
, so they can be called as a function.
- Component module
The :libraries:component
module contains the definitions of the custom view or widget.
- Framework module
The :libraries:framework
module contains different utilities that can be used by the different modules and base structures. Also the definitions of some extension methods and the navigation between fragments.
- TestUtils module
The :libraries:testutils
module contains the definitions of the test utilities.
Configuration Plugins
With App Modularization we want to gain fine-grained dependency control but we also need to make sure we don’t end up maintaining multiple configuration plugins.
For that we have the following common configuration custom plugin classes:
UnitTest
Unit tests are the fastest and easiest tests to write and the quickest to run. We write unit tests if we want to ensure that a class or method is working as intended.
I tried to apply unit test methods in data
, domain
and app
layers of Rorty application.
Tech Stacks
This project uses many of the popular libraries, plugins and tools of the android ecosystem.
- Dependencies
- Android KTX — provide concise, idiomatic Kotlin to Jetpack and Android platform APIs.
- AndroidX — major improvement to the original Android Support Library, which is no longer maintained.
- Benchmark — handles warmup, measures your code performance, and outputs benchmarking results to the Android Studio console.
- View Binding — allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.
- Lifecycle — perform actions in response to a change in the lifecycle status of another component, such as activities and fragments.
- LiveData — lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services
- Flow — flows to optimally emit state updates and emit values to multiple consumers.
- Paging — helps you load and display small chunks of data at a time. Loading partial data on demand reduces usage of network bandwidth and system resources.
- Room — persistence library provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite.
- ViewModel — designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
- Coroutines — managing background threads with simplified code and reducing needs for callbacks.
- Dagger-Hilt — dependency injector for replacement all FactoryFactory classes.
- Retrofit — type-safe HTTP client.
- Chucker — the inspection of HTTP(S) requests/responses fired.
- Coil — image loading library for Android backed by Kotlin Coroutines.
- Moshi — makes it easy to parse JSON into Kotlin objects.
- Timber — a logger with a small, extensible API which provides utility on top of Android’s normal Log class.
- RecyclerView — makes it easy to efficiently display large sets of data.
- Test Dependencies
- JUnit — a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks.
- Mockk — provides DSL to mock behavior. Built from zero to fit Kotlin language.
- AndroidX — the androidx test library provides an extensive framework for testing Android apps.
- Robolectric — industry-standard unit testing framework for Android.
- Turbine — a small testing library for kotlinx.coroutines
Flow.
- MockWebServer — a scriptable web server for testing HTTP clients.
- Coroutines— provides testing utilities for effectively testing coroutines.
- Code Analyze Plugins
How Can You Contribute?
- Open issues with suggestion of better approaches or ideas for the app.
- Connect with me on Linkedin.
- Star the Github repository.
- Follow me on Github.
Full Project
You can access the source code of the project from the link below.
Thanks 🚀
I hope it helps you. If it is useful to you, you can clap this article and follow me for such these articles.
Happy and healthy coding!
Que tengas un buen día, continuará 😊 🏄🚀