Simple Android Architecture : LiveData and event
This is one of series of Simple Android Architecture. and you can check sample code there.
This article is about Livedata and Event
When you use MVVM, you would find that there are two cases of data
- Just data which is shown on layout
- The event which should be called one time even if Activity/Fragment is recreated. like toast, dialog, starting activity.
Someone says that viewLifecycleOwner solved the issue, but In my understanding it just solved the memory leak.
And the two cases are difficult to be merged to one case, as the purpose are different.
Solutions
Then how to handle the event?
- Event class used in Android architecture-samples
- similar to MVP way. set Activity/Fragment on ViewModel by some interface.
Deep Understanding
Let’s look deep into two ways
- Event
- Pros : It’s lifecycle-aware. so, you don’t need to worry if event is called when Activity/Fragment’s is not running.
- Cons : if the data is shown on layout and also need to handle event, the readability not that good.(use peekContent() in the sample below)
- Cons : if use with Resource, too much of depth of generic type is required
MutableLiveData<Event<Resource>>().
- Activity/Fragment on ViewModel
Pros : handle multiple parameter easily
Cons : need to set Activity/Fragment on created.
Cons : lifecycle un-aware.
Cons : if event and layout both is required. need to handle separately like the sample below
Suggestion
There are merits and demerits on both way.
In my opinion Event has more merits, but still has demerits.
so, I focused on how to reduce demerits of Event class
And, I suggest the below
I used custom LiveObject class.
Explanation
When you define LiveData field, you have to consider the below
- LiveData, MutableLiveData, MediatorLiveData (3 cases)
- whether it’s Event or not. (2 cases)
- whether it’s Resource or not (2 cases)
Total, there are 12 cases to consider.
Sometimes, requirement is changed, and you have to change the type again and again.
Explanation for 1.
Normally LiveData is used in view side not to change MutableLiveData’s value.
but, mostly, we don’t mistake it. and we can verify by test code.
So, I would like to use just one class for LiveData, MutableLiveData, MediatorLiveData
Explanation for 2.
There is a data which should be shown on UI. Designer decide to show it by TextView in layout.
After that, it’s changed to AlertDialog.
In this case, the data is not changed, but we have to change MutableLiveData
Don’t you think it’s strange? even when data is not changed, but we have to change ViewModel.
so, I wrap LiveData class with custom class. and then view side decide if it’s event or not by the below way
When it’s event, use observeEvent(), if it’s not event, use observe()
isn’t it simpler and also reasonable that view side decide event or not?
Explanation for 3.
we use Resource custom class for data including state of loading, success, fail.
but, when you define LiveData for it, it’s terrible like
So, I would like to suggest
You don’t need to consider it’s Mutable or not, Event or not.
Just use these
All the 12 cases get shorten to 2 cases. now It can be manageable.
You can check sample and library code here
Happy coding :)