Skip to content

islamarr/MVI_Clean_Architecture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

53 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

MVI_Clean_Architecture_Sample

GitHub followers GitHub Repo stars GitHub forks

About this project

๐Ÿš€ Grid view List of pictures.

๐Ÿ›  Simple implementation for MVI architecture pattern and Clean Architecture.

๐Ÿ›  Unit tests included with test coverage round 100% for dataSources, repositories, UseCases and ViewModels.

๐Ÿ›  SOLID principles.

๐Ÿ›  Standard Coding Style.

๐Ÿ›  Support Tablet screens.

The Business Details

  • The application should have two screens:
    • The first screen have one view with thumbnails of all available photos returned from API.
    • When the user taps on one of the thumbnails, a second screen load to show the larger photo in the middle of the screen.
  • Image Urls should be edited by omitting the proxy part โ€œm.mobile.de/yams-proxy/โ€, prepending โ€œhttps://โ€ and appending โ€œ?rule=mo-640.jpgโ€ for normal images or โ€œ?rule=mo-1600.jpgโ€ for larger one.
  • Display a grid list with 2 columns in the portrait mode and 3 columns in the landscape mode.

Demo

demo

Architecture pattern Used

MVI

architecture pattern

Testing Coverage

Testing

Libraries & Tools Used

  • Foundation - Components for core system capabilities, Kotlin extensions and support for multidex and unit testing.

  • Test - An Android testing framework for unit and runtime UI tests.

  • Architecture - A collection of libraries that help you design robust, testable, and maintainable apps. Start with classes for managing your UI component lifecycle and handling data persistence.

    • View Binding - To more easily write code that interacts with views.
    • Lifecycles - Create a UI that automatically responds to lifecycle events.
    • Navigation - Handle everything needed for in-app navigation.
    • ViewModel - Store UI-related data that isn't destroyed on app rotations. Easily schedule asynchronous tasks for optimal execution.
    • Repository - A Module that handle data operations, You can consider repositories to be mediators between different data sources.
    • Retrofit - A simple library that is used for network transaction.
    • Hilt: For dependency injection
    • Kotlin Coroutines For managing background threads with simplified code and reducing needs for callbacks.
    • Kotlin Flows - A stream of data that can be computed asynchronously.
    • Glide - For image loading.
  • Other tools/plugins

    • Obfuscation, Code shrinking - Obfuscation is to reduce your app size by shortening the names of the appโ€™s classes, methods, and fields. Shrinking to make the app as small as possible.
    • Google material design to build high-quality digital experiences for Android.
    • SonarLint plugin - Static Code Analysis that identifies and helps you fix quality and security issues as you code.

Technical choices

MVI vs MVVM

  • A consistent state during the lifecycle of Views.
  • As it is unidirectional, Data flow can be tracked and predicted easily.
  • It ensures thread safety as the state objects are immutable.
  • Easy to debug, As we know the state of the object when the error occurred.
  • It's more decoupled as each component fulfills its own responsibility.
  • Testing the app also will be easier as we can map the business logic for each state.
  • Read more

RecyclerView vs listview

  • In RecyclerView, it is mandatory to use ViewHolder pattern Which optimize the performance.
  • DiffUtil callback Which optimize the performance.

Activities vs Fragments

  • I have used a single-activity architecture which allowed me to take full advantage of the Navigation component, which mean that a single activity that manages and host multiple fragments.
  • The fragment is more lite weight than Activity.
  • I also added simple animation in navigation between fragments.

Hilt vs Dagger2 vs Koin

  • Hilt is built on top of the Dagger, and it comes with some advantages like simplify Dagger code and create a standard set of components and scopes to ease setup.
  • As this project is simple, Hilt is the best one. For more complex projects I will go with Dagger2 to avoid some limitation of hilt.
  • Hilt does not need factories for ViewModel, koin need.
  • Hilt generate the code in the compile time, while koin in runtime.

Coroutines vs RxJava

  • Coroutines come with many advantages over RxJava, beside that it is Kotlin-friendly design pattern, it is:
    • Lightweight: You can run many coroutines on a single thread due to support for suspension.
    • Fewer memory leaks: Use structured concurrency to run operations within a scope.
    • Built-in cancellation support.
    • Many Jetpack libraries include extensions that provide full coroutines support.

Retrofit vs Volley

  • Retrofit has a well-designed structure.
  • Suspend function support.

Moshi vs GSON

  • Moshi is a Kotlin-Friendly converter.
  • Moshi has better and more human-readable serialization failed messages.
  • Moshi has Code-gen adapter for Kotlin, This is great! With help of annotations, you make the Serialization/Deserialization much faster and bypass the old slow reflection method that Gson uses!

Glide

  • Glide very effective for almost any case where you need to fetch, resize, cache and display a remote image.
  • Support thumbnail and placeholder which I needed in this project.

What's next

While the project scale up, Some points should be considered:

  • Parent classes should be added for common used classes like ViewModels and Use Cases.
  • Analytics and tracking system should be implemented to provide insight on app usage and user engagement.
  • Caching mechanism should be added to reduce network calls and improve the performance.
  • Pagination should be handled from backend and client side.

Other Projects