An android app built using Kotlin following Multi-Module Clean Architecture MVVM

Overview

NotFlix

NotFlix

     

Notflix ๐Ÿ› ๏ธ Work In Progress ๐Ÿ› 

An android app built using Kotlin that consumes TMDB API to display current trending, upcoming and popular movies ๐Ÿฟ and tvshows ๐ŸŽฌ . 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 for a few reasons:

  1. To learn the approch of implementing clean architecture and SOLID principles in an android app.
  2. To learn libraries/tools supported by Google and most of the android development communities.
  3. To experiment with modularization and dynamic feature modules.
  4. To learn implementation of Picture-in-Picture.
  5. Demonstrate best developement practices by utilizing up to date tech-stack .

Table Of Content.

Prerequisite.

In order to be able to build the application you'll need to change the api key in gradle.properties. First and formost you need to generate your own api key by creating an IMDB account and generating an api key.

Disclaimer.

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.

So let's get started ...

Architecture.

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.

Clean Architecture Diagram

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.

S.O.L.I.D Principles.

  • 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.

Layers.

1. Domain.

This is the core layer of the application. The domain layer is independent of any other layers thus ] domain models and 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:

  • Models: Defines the core structure of the data that will be used within the application.

  • Repositories: Interfaces used by the use cases. Implemented in the data layer.

  • Use cases/Interactors: 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 operator โ€œinvokeโ€, so they can be called as a function.

2. Data.

The data layer is responsibile for selecting the proper data source for the domain layer. It contains the implementations of the repositories declared in the domain layer.

Components of data layer include:

  • Models

    -Dto Models: Defines POJO of network responses.

    -Entity Models: Defines the schema of SQLite database.

  • Repositories: Responsible for exposing data to the domain layer.

  • Mappers: They perform data transformation between domain, dto and entity models.

  • Network: This is responsible for performing network operations eg. defining API endpoints using Retrofit.

  • Cache: This is responsible for performing caching operations using Room.

  • Data Source: Responsible for deciding which data source (network or cache) will be used when fetching data.

3. Presentation.

The presentation layer contains components involved in showing information to the user. The main part of this layer are the views and viewModels.

Tech Stack.

This project uses many of the popular libraries, plugins and tools of the android ecosystem.

Patterns.

  • Observer Pattern - The observer pattern is a software design pattern that defines a one to many dependencies between objects so that one object changes state, all of its dependents are notified and updated automatically.

  • Repository Pattern: The repository pattern is a software design pattern that restricts us from work directly with the data in the application and creates new layers for database operations, business logic, and the application's UI.

  • UseCase Pattern - UseCase pattern is a software design pattern that is used to bridge the gap between business and system models without altering requirements contents nor preempting architectural options.

Libraries.

  • Hilt - Dependency Injection library.

  • Jetpack

    • 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.
    • 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.
    • 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.
    • Data Binding - Allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.
    • Room - Provides an abstraction layer over SQLite used for offline data caching.
    • Navigation Component-Component that allows easier implementation of navigation from simple button clicks to more complex patterns.
  • MotionLayout - Helps create and manage beautiful UI animations.

  • Retrofit - Type-safe http client and supports coroutines out of the box.

  • GSON - JSON Parser,used to parse requests on the data layer for Entities and understands Kotlin non-nullable and default parameters.

  • OkHttp-Logging-Interceptor - Logs HTTP request and response data.

  • Coroutines - Library Support for coroutines.

  • Flow - Flows are built on top of coroutines and can provide multiple values. A flow is conceptually a stream of data that can be computed asynchronously.

  • Timber-Library for easier logging.

  • Material Design - Build awesome beautiful UIs.

  • Glide- Image Library from loading images from the database and cacheing in memory.

  • kotlinx.coroutines - Library Support for coroutines,provides runBlocking coroutine builder used in tests.

  • Truth - Assertions Library,provides readability as far as assertions are concerned.

  • MockWebServer - Web server for testing HTTP clients, verify requests and responses on the TMDB API with the retrofit client.

Plugins

  • 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 chanes to the main branch.
  • KtLint - The project uses KtLint to check for syntax correctness.

Related Resources.

In this section i've included some resources ie. articles and GitHub reposirtories that i used to learn about Clean Architecture:

  1. The clean code blog by Robert C. Martin.
  2. A detailed guide on developing android apps using clean architecture pattern Medium article.
  3. Clean Architecture Component Boilerplater GitHub repo .
  4. The Force GitHub repo by David Odari demonstrating using clean architecture pattern
  5. Clean architecture tutorial for android article by Raywenderlich which is really beginner friendly.
  6. Clean architecture in android Medium article.
  7. Intro to app architecture and Intro to app modularization articles by ProAndroidDev.

Other Helpful Resources.

In this section i've included resources that are not related to clean architecture but were really helpful in learning other android components and tools:

  1. Pokedex GitHub repo by Ronnie Otieno demonstrating how to use various jetpack components.
  2. Fundamentals of testing from the official android developers site.
  3. Android MotionLayout Tutorial โ€“ Collapsing View blog post on how to create a collapsing view with MotionLayout.
  4. MotionLayout โ€“ Collapsing Toolbar blog post demonstrating how to create a collapsing toolbar using MotionLayout
  5. Introduction to Github Actions for Android blog by Mindorks on how to set up GitHub actions for an android project.

Demo

These are the app's screenshots:

You might also like...
A quiz app built with trivia api. This app was built with mvvm architecture, dagger-hilt, retrofit, room database, and navigation components.
A quiz app built with trivia api. This app was built with mvvm architecture, dagger-hilt, retrofit, room database, and navigation components.

A quiz app built with trivia api. This app was built with mvvm architecture, dagger-hilt, retrofit, room database, and navigation components.

Food Recipes - Android application built with Jetpack compose, MVVM and clean architecture approach.
Food Recipes - Android application built with Jetpack compose, MVVM and clean architecture approach.

Food Recipes Android application that consuming (https://spoonacular.com/food-api) "Recipes api". It has been built with clean architecture principles

Android app which fetches a sample movies list to display. Built using Kotlin and latest Android tech stack, with an approach to clean architecture.
Android app which fetches a sample movies list to display. Built using Kotlin and latest Android tech stack, with an approach to clean architecture.

movies-sample-app This is an Android app which fetches a sample movies list to display. Built using Kotlin and latest Android tech stack, with an appr

SimpleCloud-haste-module - SimpleCloud module for uploading the logs of your services to hastebin

SimpleCloud Haste Module A SimpleCloud Module for uploading the current logs of

BuildConfiguration information for use in multi-module, or Kotlin Multiplatform common code

component-build-configuration A small library supporting Kotlin Multiplatform for utilizing BuildConfiguration details from common code and across mod

Dose a Android app that reminds you medications exactly when your body needs them, building entirely using Kotlin and Jetpack Compose with MVVM + Clean Architecture
Dose a Android app that reminds you medications exactly when your body needs them, building entirely using Kotlin and Jetpack Compose with MVVM + Clean Architecture

๐Ÿ’Šโฐ Dose is a work-in-progress Android app that reminds you medications exactly when your body needs them, building entirely using Kotlin and Jetpack Compose with MVVM + Clean Architecture

๐Ÿ›’A Minimal Expense E-Commerce App built to demonstrate the use of modern android architecture components [Navigation, Room, MotionLayout, etc..] with MVVM Architecture. โœ”
๐Ÿ›’A Minimal Expense E-Commerce App built to demonstrate the use of modern android architecture components [Navigation, Room, MotionLayout, etc..] with MVVM Architecture. โœ”

E-Store A Simple E-Commerce App ๐Ÿ“ฑ built to demonstrate the use of modern android architecture component with MVVM Architecture ๐Ÿ— . Made with love โค๏ธ

A Simple Expense Tracker App ๐Ÿ“ฑ built to demonstrate the use of modern android architecture component with MVVM Architecture
A Simple Expense Tracker App ๐Ÿ“ฑ built to demonstrate the use of modern android architecture component with MVVM Architecture

Expenso ๐Ÿ“Š A Simple Expense Tracker App ๐Ÿ“ฑ built to demonstrate the use of modern android architecture component with MVVM Architecture ๐Ÿ— . Made with

Simple Android movies app using MVVM clean architecture.
Simple Android movies app using MVVM clean architecture.

Simple Android movies app using MVVM clean architecture.

Comments
  • why RepositoryImpls are using flowOf()

    why RepositoryImpls are using flowOf()

    I want to thank you first, then I hope you answer my question, it is a question, not an issue ๐Ÿ˜ƒ

    All ApiService methods are returning suspend functions suspend fun fetchMovieDetails(movieId: Int): MovieDetailsDto?

    why are MovieDetailsRepositoryImpl methods had converted toflowOf () e.g

        override suspend fun getMovieDetails(movieId: Int): Flow<MovieDetails?> {
            val networkResponse = apiService.fetchMovieDetails(movieId = movieId)
    
            return flowOf(networkResponse?.toDomain())
        }
    

    what are the benefits of making all repo methods in kotlin flow, where consuming suspend fun is easier than flow? also combing two suspend funs is much easier to combine two flows to create new usecases.

    I see this pattern I would like to know the secret behind ๐Ÿ˜Ž

    question 
    opened by periva101 3
  • Language changes is not affecting the app

    Language changes is not affecting the app

    I have changed the language to French however the sentences/presentation are still in english

    PS : I have killed and relaunched the app same problem Maybe the movies are stored on local database and not reloaded when the language changes ?

    enhancement 
    opened by peyrusse 2
  • App Crash when accessing detailed movies

    App Crash when accessing detailed movies

    1/ Launch the App 2/ Select a movie on the home page to access to the detail page 3/ The view starts to display then crashes with this error message : android.database.sqlite.SQLiteException: no such column: true (Sqlite code 1 SQLITE_ERROR): , while compiling: SELECT isFavorite FROM Movies Table WHERE id=? AND isFavorite=true, (OS error - 11:Try again) at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1030) at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:637) at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:610) at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:66) at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37) at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1482) at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1452) at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.query(FrameworkSQLiteDatabase.java:161) at androidx.room.RoomDatabase.query(RoomDatabase.java:446) at androidx.room.util.DBUtil.query(DBUtil.java:83) at com.vickikbt.cache.daos.MoviesDao_Impl$10.call(MoviesDao_Impl.java:594) at com.vickikbt.cache.daos.MoviesDao_Impl$10.call(MoviesDao_Impl.java:591) at androidx.room.CoroutinesRoom$Companion$createFlow$1$1.invokeSuspend(CoroutinesRoom.kt:122) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:929)

    opened by peyrusse 2
  • Images not showing

    Images not showing

    Images don't load with the error message below

    W/Glide: Failed to find GeneratedAppGlideModule. You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler in your application and a @GlideModule annotated AppGlideModule implementation or LibraryGlideModules will be silently ignored

    opened by Hoossayn 2
Owner
Victor Kabata
Android Dev(Kotlin || Java) && Backend Golang
Victor Kabata
Easy Note: Building a Notes app using MVVM, JetPack Compose with a clean multi-module architecture approach.

Easy Note Easy Note: Notes app using JetPack Compose and MVVM with a clean architecture approach. This app shows the usage of the new Navigation Archi

Akhilesh Patil 10 Dec 17, 2022
This project shows trending github repositories using MVI (Model View Intent) using kotlin flows and multi module clean architecture

GithubTrendingMVIFlow Build Architecture: This project shows trending github repositories using MVI (Model View Intent) using kotlin flows and multi m

Zulqurnain Haider 0 Jun 2, 2022
To Do List App is built in Kotlin using Material 3, Data Binding, Navigation Component Graphs, Room persistence library, Kotlin coroutines, LiveData, Dagger Hilt, and Notifications following MVVM Architecture.

ToDoListApp ToDoList App demonstrates modern Android development with Hilt, Coroutines, LiveData, Jetpack (Room, ViewModel), and Material 3 Design bas

Naman Garg 10 Jan 8, 2023
๐Ÿš€ Sample Android Clean Architecture on Rorty App focused on the scalability, testability and maintainability written in Kotlin, following best practices using Jetpack.

Android Clean Architecture Android Clean Architecture in Rorty is a sample project that presents modern, approach to Android application development u

Mr.Sanchez 0 Dec 28, 2021
NewsSpac-MVVM-CleanArch-TDD - The App uses MVVM architecture together with Clean architecture

Aplicativo NewsSpace Arquitetura O App utiliza a arquitetura MVVM em conjunto co

null 1 Feb 11, 2022
A wallpaper app Built with MVVM clean architecture using pixabay api

wallpaper get your API key at pixabay in order to test the APP! This project demonstrates the use of jetpack compose and modularization. it is complet

chima james 1 Oct 23, 2021
A movies application built Using clean architecture and MVVM (Model-view-viewModel).

Movies-App This is a movies application which fecthes upcoming and popular movies from the movie Database(TMBD). It is built Using clean architecture

Felix Kariuki 4 Dec 20, 2022
๐Ÿ“š Sample Android Components Architecture on a modular word focused on the scalability, testability and maintainability written in Kotlin, following best practices using Jetpack.

Android Components Architecture in a Modular Word Android Components Architecture in a Modular Word is a sample project that presents modern, 2020 app

Madalin Valceleanu 2.3k Jan 3, 2023
A sample demo app which has Clean Architecture with MVVM , UI built with Jetpack Compose

A sample demo app (two screen todo list app) which has Clean Architecture with MVVM , UI built with Jetpack Compose and includes Modern Android Development Best Practices with components

BHAVNA THACKER 21 Dec 13, 2022