Part 2: Reactive architectures. MVVM + MVI + RxJava

Taras Morskyi
AndroidPub
Published in
4 min readFeb 12, 2019

Previous on Medium,

Part 1 of this series introduces Reactive architecture with MVI pattern to make your project able to use whole power of RxJava instead of wrapping network requests into it.

TL;DR

In this part I introduce MVVM provided by Google in the way which allows us to keep all advantages ofReactive architecture with MVI introduced in previous part. With this solution ViewModel becomes an Observer instead of Activity/Fragment(View), but it keeps the same way of View sending events.

Switching roles

MVVM introduced by Google is great to deal with one of well known Lifecycle problems as screen rotation. With just RxJava you can easily make your own LiveData with BehaviorSubject which works in exactly the same way. Bigger problem is to create ViewModel with regular Dependency Injection without connecting it to Application level. This is why a lot of developers stick with Google’s MVVM.

By introducing MVVM into project its View loses any sense of being an Observer because any data which has to be saved when Activity recreates is now held in ViewModel. With this small changes ViewModel becomes Observer as a holder of data required by View.

ViewModel is Observer now, View receives required data through LiveData, and does not receive any event from reactive chains anymore, but it still triggers new events after users actions. Now there is one small problem. What if we need to do something else except setting new List into RecyclerView or change text in TextView? To help with this problem it’s required to introduce third type of event which will be send to View from ViewModel through LiveData if it should do something except change layout. At the same time it is a good idea to rename an old event to make names connected to current patterns:

  • xViewModelEvent — event sent from View to ViewModel to trigger reactive chain to do required business logic
  • xUiModel — result of reactive chain with all data required for updating View
  • xViewEvent — event sent from ViewModel to View through LiveData to trigger any View action different from layout changes (open Dialog, open another Activity etc.)

Practice

This part does not contain so much theory, so it’s time to show how does it look in practice.

ViewModelEvent/UiMode/ViewEvent

Event classes are the same as they were in part 1 of this series: sealed class which extends Base class to be used in a safe way with Generics and implementations of extended classes which represent all required events or results.

View

This time there is nothing to show in View. It contains ViewModel saved in field to start observing LiveData and send event to trigger reactive chain of business logic.

ViewModel

From this moment ViewModel is the center of the Universe. Let’s start from Base of this ultimate Universe.

Here are the key parts of BaseViewModel:

  • It requires now 3 instead of 2 generics to describe all required events
  • It’s now Observer
  • On initialization it describes where to pass event received in Subject and subscribes for results to itself
  • Subscription is saved in onSubscribe() to be able to dispose it when it is required
  • In onClear() dispose() is called to loose all connections to Observables
  • In the same way as before, events are received in event() function which triggers chain of reactive logic in Subject
  • onEvent() is still required to identify received events

With this powerful BaseViewModel final implementation does not require a lot of extra code to implement everything.

Only a few parts of implementation are interesting for now:

  • By extending BaseViewModel it describes all required event classes
  • onEvent() identifies events in the same way as it is without ViewModel in MVI
  • onNext() sets data/event which has to be setted/called in View
  • If View has to do some extra action different from changing layout ViewEvent has to be passed into viewEventObservable (LiveData)

Conclusion

This architecture is fair enough to use in most projects if team doesn’t want to do some extra complex separation. It gives you everything for what ViewModel was created with the power of full RxJava. However, if team is not scared of challenges and at the same time easy to scale project with faster builds is your goal, you are welcome to read next part of this series about modularizing projects for Android.

--

--