简体   繁体   中英

Replace LiveData with RxJava in MVVM artitecture

LiveData seems very useful since it only notifies the view when the view is in an active state. It also stores and returns the last value to new subscribers right after subscribe.
My question is how to achieve the same thing with only RxJava?

Since Rx is a fully functional reactive solution combining it with another reactive solution doesn't seem right. I prefer if I could just remove LiveData from the project.

I know about https://github.com/trello/RxLifecycle and https://github.com/uber/AutoDispose but what they do is unsubscribing from the stream. I don't want that. I want my stream to exist as longs as view model is alive but my activities to start and stop listening to the steam base on lifecycle.

any suggestion will be appreciated

You can go with 2 solutions:

  • first one you can use LiveDataReactiveStreams to convert from a livedata stream to a rx stream and vice versa.

  • second one you may definitely get rid of livedata and use BehaviourSubject (a rx stream that store last value as live data), but as you said you'll have to subscibe/unsubscribe when your view resume/pause

You can definitely do the whole thing with only RxJava. That's what I did with my team in many apps:

Regarding life-cycle management, we do two things:

  1. We use the ViewModel from the Architecture Components to retain the ViewModel's states when the View gets destroyed https://developer.android.com/topic/libraries/architecture/viewmodel

  2. We subscribe to our ViewModel's RxJava-Properties in our View/Fragment and dispose the subscription eg in onStop/onDestroy. RxLifecycle as you mentioned is actually of great help there. You cannot or rather should not retain the subscriptions when the View gets destroyed. It creates a memory leak since the subscription still has a hard reference on your View/Fragment. Also, the whole thing will crash if your ViewModel's RxProperties fire when the View was destroyed (eg when a server request returns after closing the app). So you need to dispose your subscriptions, no way around that in Android.

As @Samuel mentioned a BehaviourSubject/PublishSubject (depending on the case) is a great fit to provide Inputs to a ViewModel. The Outputs will be Observables which you subscribe to. Your ViewModel could have an interface with Outputs and Inputs like this:

interface TasksViewModel {
        // inputs
        Observer<Task> taskAddedTrigger();
        Observer<Task> taskClickedTrigger();
        Observer<Task> taskCompletedTrigger();

        // outputs   
        Observable<Boolean> isLoading();
        Observable<List<Task>> tasks();
}

Your ViewModel then just uses RxJava to map inputs to outputs in a very functional style. You Fragment supplies Inputs to the ViewModel whenever User input is received. It subscribes to Outputs and updates the user interface accordingly when the ViewModel's Output changes. Here is a compact article where I summarize this whole Architecture (MVVM+RxJava)

Let me know if you run into trouble with any details of this approach. I used this architecture in many apps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM