Giter Site home page Giter Site logo

lyhoangvinh / kotlin-mvvm-architecture Goto Github PK

View Code? Open in Web Editor NEW
13.0 0.0 6.0 2.36 MB

This repository contains a detailed sample app that implements MVVM architecture in Kotlin using Dagger2, Room, RxJava2...

License: GNU General Public License v3.0

Kotlin 71.48% Java 28.52%
mvvm mvvm-android dagger2 room database rxjava2 rx-android-sample retrofit2 kotlin kotlin-mvvm-rxjava-room-dagger

kotlin-mvvm-architecture's Introduction

Kotlin MVVM Clean Architecture

This repository contains a detailed sample app that implements MVVM architecture in Kotlin using Dagger2, Room, RxJava2...

MVVM Design Pattern

The main players in the MVVM pattern are:

  • The View — that informs the ViewModel about the user’s actions

  • The ViewModel — exposes streams of data relevant to the View

  • The DataModel — abstracts the data source. The ViewModel works with the DataModel to get and save the data

The MVVM pattern supports two-way data binding between the View and ViewModel and there is a many-to-one relationship between View and ViewModel.

Libraries

Dependency Injection: Dagger2

In order to reduce boilerplate and the steps required to create new Activities and Fragments, Dagger provides some base classes called DaggerApplication, DaggerAppCompatActivity and DaggerFragment.

These contain applicationInjector, AndroidInjection and AndroidSupportInjection respectively which were supposed to be included in all classes and fragments.

From the Project Pane, we have the following classes:

MyApplication class

A class which extends the DaggerApplication class.

This is a base class in android that contains all android components such as activities, services, broadcast receivers etc.

class MyApplication : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> =
        DaggerAppComponent.builder().create(this)

    companion object {
        private lateinit var instance: MyApplication

        fun getInstance() = instance
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
    }
}

AppComponent class

This class combines all the module classes used in the app for compilation by the Dagger 2 library.

@Singleton
@Component(
    modules = [AndroidSupportInjectionModule::class,
        AndroidInjectionModule::class,
        AppModule::class,
        NetworkModule::class,
        DataModule::class,
        BuildersModule::class]
)
interface AppComponent : AndroidInjector<MyApplication> {
    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<MyApplication>()
}

ActivityBuilder class

This class houses all Activities and Fragment Modules.

@Module
abstract class BuildersModule {

    @ContributesAndroidInjector(modules = [MainActivityModule::class])
    abstract fun mainActivity(): MainActivity

    @ContributesAndroidInjector(modules = [TestActivityModule::class])
    abstract fun testActivity(): TestActivity

    @ContributesAndroidInjector(modules = [TestFragmentModule::class])
    abstract fun testFragment(): TestFragment
}

...

Next setting up Base Activity, Base Fragment, BaseViewModel

BaseActivity

An abstract class created which extends the DaggerAppCompatActivity class. Per adventure you have some other methods that would be used in all activities, you could put them in this class while the activities extend it.

abstract class BaseActivity : DaggerAppCompatActivity()
BaseFragment

An abstract class which extends the DaggerFragment class. Including methods as explained in BaseActivity also applies here.

abstract class BaseFragment<B : ViewDataBinding> : DaggerFragment()
BaseViewModel

An abstract class which extends the ViewModel class

abstract class BaseViewModel : ViewModel()

Repository

Why the Repository Pattern ?

  • Decouples the application from the data sources

  • Provides data from multiple sources (DB, API) without clients being concerned about this

  • Isolates the data layer

  • Single place, centralized, consistent access to data

  • Testable business logic via Unit Tests

  • Easily add new sources

So our repository now talks to the API data source and with the cache data source. We would now want to add another source for our data, a database source.

On Android, we have several options here :

  • using pure SQLite (too much boilerplate)

  • Realm ( too complex for our use case, we don’t need most of it’s features)

  • GreenDao ( a good ORM, but I think they will focus the development on objectbox in the future)

  • Room ( the newly introduced ORM from Google, good support for RXJava 2 )

I will be using for my example Room, the new library introduced by Google.

Thread-safe live data to resolve this issue: when perform not in main Thread. (almost case is in testing)

class SafeMutableLiveData<T> : MutableLiveData<T>() {
    override fun setValue(value: T) {
        try {
            super.setValue(value)
        } catch (e: Exception) {
            // if we can't set value due to not in main thread, must call post value instead
            super.postValue(value)
        }
    }
}

Execute room

    fun execute(action: () -> Unit) {
        Completable.fromAction {
            action.invoke()
        }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe()
    }

Contributing to Android Kotlin MVVM Architecture

All pull requests are welcome, make sure to follow the contribution guidelines when you submit pull request.

App

Project development follow Advance MVVM Template with Dagger 2, RxAndroid, Room, LiveData and Unit Testing.

Sample app:

Download from Google Play

License

Copyright 2018 LyHoangVinh.

Licensed under the the GPL-3.0 license.

See the LICENSE file for the whole license text.

kotlin-mvvm-architecture's People

Contributors

lyhoangvinh avatar vinhpaxcreation2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.