In this article i will explain a brief overview about how i implemented MVVM with clean architecture in my Android application.
We are going to implement a sample Android Application including Google Architecture Component based on MVVM and repository pattern using Android Jetpack (ViewModel, LiveData, Room, Paging, Navigation, DataBinding), Retrofit, Dagger2 etc.
Application is fully build in kotlin and we will use kotlin coroutines that can be used for simplifying async code or non blocking codes.
Architecture overview
This application uses clean architecture based on MVVM and Repository patterns following Google guidelines.
The goal of introducing Android Jetpack
- Aims to leverage advanced kotlin feature in order to reduce boilerplate.
- Provides higher level of abstraction over Android SDK, allows developer to express complex task in simpler way.
Clean Architecture assumes the separation of UI (Activity
/ Fragment
/ View
) , Presentation(ViewModel) and Data(Repository) layers. Viewmodel designed to store user related data in life-cycle conscious way and automatically manages UI component via LiveData.
Repository servers as a data source, Viewmodel is not aware about the source of data. Repository class decide the source of data whether local or remote that need to send back to the user.
Show List of News to User
Lets develop an application screen which list the latest news from the REST API and show them to the user.
The full source code of the project including all library can be found on below GitHub link.
Dependency Used
The goal of this application is to show case current Architecture state using tools developed by google called Android Jetpack and other famous third party libraries.
Jetpack is a set of component to make great Android Apps. In Jetpack existing libraries and components are arranged into four categories.
Model
Lets develop and Android app with the list of news. We will load list of news and show them to the user. We will support fetch data from REST Api in part 1, and will support Offline caching in part 2.
News Listing Screen
We have started by writing a layout for the first fragment NewsListingFragment.kt and its layout news_list_layout.xml. The DataBinding library allows to bind the UI components into the layout in a declarative method other than programmatically.
Then lets add news_list_row.xml
In order to display items in list and reuse view resources lets write NewsListingAdapter
.
Lets write NewsListingFragment
with viewModel
injected.
In NewsListingFragment LiveData start observing LiveData<NewsResponse>
from viewModel
and updates the UI in a lifecycle aware way.
Dagger 2 Dependency Injection
Dagger 2 developed by google provides dependency injection on Android Applications. Dependency injection isn’t just for testing. It also makes it easy to create reusable, interchangeable modules.
Now let us take the advantage of dependency injection to let the NewsRepository into the viewModel.
Since Fragmentx
is initialised by Android SDK
, we can not inject viewModel on construction phase. Therefore we will inject it via ViewModelFactory
.
Injecting Retrofit
I this process we have to create a module with retrofit instance into the ViewModel. We will name this module as AppModule
and placed in the package name called di
which has to be added to the root package of your application.
We will also make the module and provider methods Singleton as we do not want to instantiates those each time we use it:
Presentation (MVVM, Viewmodel, LiveData)
The viewModel and liveData is lifecycle aware and our NewsListingViewModel
is very simple. It has only NewsLisitingRepository
as a dependency in order to provide data for the NewsLisitingFragment.
Repository-Kotlin Coroutines
The Repository
serves as an abstract source of data for Presentation Layer (viewModel
). Repository should choose which data source it truth.
Here LiveData
and Coroutines
come to rescue and simplify code. Let's look at NewsLisitingRepository.
We are using extension function liveData()
from CoroutineLiveData.kt
class of LiveData
library. liveData()
function accepts Coroutine Dispatcher
in order to choose running tread.
There are 4 types of Dispatchers
:
Default (Designed for heavy computational work)
Main (Main thread operating with UI objects)
IO (Designed for offloading blocking IO tasks like network, database operations)
Unconfined (Not confined to any specific thread)
In our case Dispatchers.IO
is exactly what we need. We use Coroutines suspend functions
in order to load data. We use emit() function, which automatically notify observer on Main UI thread.
Networking -Retrofit and Kotlin Coroutines
Kotlin coroutine is a light weight thread. Coroutines are way cheaper than actual Java Thread. So a developer can fire and forget a long number of coroutine without any headache. Coroutines are more like a task that can be executed in any thread.
Lifecycle library has three main artifacts that provide three main API to run with coroutines.
Global Scope in Lifecycle-runtime
Livedata Scope in lifecycle-viewmodel
Viewmodel Scope in lifecycle-livedata
Navigation Component
Navigation component structures navigation and show all transitions in one diagram via xml. This xml is known as navigation graph, its very helpfull to see all the controls in single graph. Library avoid boilerplate code for the fragment state and backstate management.
Navigation component works greatly for the basis application. However the application with more complex UI such as navigation drawer Bottom NavigationView and other navigation patterns, this become bit complex and require customization. So keep in mind scale of your application when you decide to use Navigation component.
Conclusion
So we now have seen a complete implementation of the MVVM- Clean architecture with all Android Architecture Components.
That’s We have just completed an application using Kotlin Coroutines, Android Jetpack(ViewModel, LiveData, Navigation, DataBinding), Retrofit and Dagger 2.
Kotlin Coroutines serve great for basic application and have potential for big scale solutions.
The full source code of the project including all library can be found on below GitHub link.
Part 2 : Paging Library | Room | WorkManager