android, what is the overhead the LiveData would bring in - android

Question about using LiveData.
With LiveData you get for free that something like:
listener/subscriber support;
lifeCycle awareness/management;
cross thread marshaling, etc.
We could just use the liveData as the mechanism of delivering between any data repository to ui presentation for almost any case.
However in order to using it, it must bring in some objects that it needed, just like if you were to implement those features yourself there must be some supporting classes to be implemented.
Wondering how much/big the overhead it might be? Is it at a lever of could be simply ignored?
The case like do a search it could use LiveData, ui asking result from repository and observes a liveData, the repository posts the result and UI gets notified.
The same could be done without liveData as well (i.e. run coroutines suspended function to fetch from repository directly).
Would like to know whether the LiveData will bring some unnecessary objects, or the benefit over weigh them.
Saw some post but did not find an official guid on when should use/ or not use LiveData, or LiveData is not suitable for such and such cases. Maybe it's just no overhead at all?
Any suggestion/thought?

When working with MVVM (Model View ViewModel) you have two primary options to send data from the ViewModel to the View (updating the View).
Data Binding
LiveData
If you don't want to complicate the XML layout we usually use LiveData, which works based on Observer Design Pattern.
Using Kotlin Coroutines won't bring the full-featured package of LiveData.
With LiveData you have postValue from another thread to main thread,
You can observe changes from inside the view, and ...
PLUS: Kotlin Coroutines are for multithreading which is not relevant to LiveData, a component for holding data.

Related

LiveData Vs StateFlow: Should we switch from Live data to State Flow?

I have come across articles that recommend switching to StateFlow.
Like the one here.
Also in the new Android studio, StateFlow support is automatically included in the functionality of data binding, including the coroutines dependencies.
Live data is already in use in most of the apps.
Should we migrate from LiveData to StateFlow? What are the benefits?
There is not much difference between State Flow and Live Data. The Main difference come in that State Flow requires an Initial value hence no need to check for nullability. The Second Difference come in unregistering the consumer; Live Data does this automatically when the view goes to STOPPED state while State Flow does not. To achieve similar behaviour as Live Data, you can collect the flow in a Lifecycle.repeatOnLifecycle block.
Benefits of State Flow
State flow is included in coroutines library and can be used in Multiplatform Projects
Using one API in your project(Flow), not two (LiveData and Flow).
It's Kotlin, Why Not
It depends on what you want,
If you want a manual, full and versatile control over the app , go for state flow
If you want a partially automatic or relatively easy-to-use method for your app , I will say - stick with live data
In case If you want to know my personal opinion, it's state flow, as i prefer control over easy-to-use. I don't mind writing a few extra lines for it as it can be useful for me sometimes.
Think of it like using a soda opener for soda and using a nail cutter
I can do it with both but the soda opener Is easy to use in this case but , don't have much versatility like nail cutter.
And at the end of the day , I use state flow everytime because, I am lazy to learn live data for some projects as state flow can do what live data can even though live data will be much easier.
And you should decide what you want to choose and if you're not as lazy as me , I recommend go with both and use the one which is suitable each time.
Cheers.
Flow is the best practice
Livedata is used to observe data without having any hazel to handle lifecycle problems. Whereas Kotlin flow is used for continuous data integration and it also simplified the asynchronous programming.
Take Room Library as an example. First, it used livedata to transmit data from the database to UI. It solved most of the existing problems. But when there are any future changes in the database livedata is helpless in this situation.
After a while, the room used Kotlin flow to solve this problem. With Flow as return-type, room created a new possibility of seamless data integration across the app between database and UI without writing any extra code
read this article on medium website
In Android, LiveData and State are two classes that can be used to hold and observe data in your app. Both classes are part of the Android Architecture Components library, which is a set of libraries for building robust, testable, and maintainable apps.
LiveData is a data holder that is lifecycle-aware, meaning it only delivers updates to observers that are in an active state. It is useful for holding data that needs to be observed and updated in the UI, such as data from a network request or a database query.
State is a data holder that represents an immutable state value that can be observed. It is useful for holding data that does not change often, or data that should not be modified directly.
Which of these classes is "best" to use depends on your specific needs and requirements. Here are a few factors to consider when deciding between LiveData and State:
Mutability: LiveData is mutable, meaning its value can be changed, while State is immutable, meaning its value cannot be changed directly.
Lifecycle awareness: LiveData is lifecycle-aware, while State is not.
Transformation: LiveData supports transformation through the use of the Transformations class, while State does not.
In general, if you need to hold and observe data that needs to be updated in the UI and you want the data to be lifecycle-aware, LiveData is a good choice. If you need to hold and observe data that is immutable or does not change often, State is a good choice.
It is also worth considering whether you need to transform or map the data being held and observed. If you do, LiveData is a better choice because it supports transformation through the Transformations class.

Discuss using Kotlin Coroutines with MVVM?

I am using Kotlin Corountines with MVVM pattern and faced a problem: The data processing part is being done inside the ViewModel. While the repository seems not really necessary. When the application needs to call many APIs, the ViewModel will swell. What is everyone's solution to this problem? Thank you
The repository is needed, because in the case when you have a large app and gave too much responsibility to the ViewModel it's broke the separation of concerns principle.
Basically in the Andorids Guide to app architecture :
A first idea for implementing the ViewModel might involve directly
calling the Webservice to fetch the data and assign this data to our
LiveData object. This design works, but by using it, our app becomes
more and more difficult to maintain as it grows. It gives too much
responsibility to the UserProfileViewModel class, which violates the
separation of concerns principle. Additionally, the scope of a
ViewModel is tied to an Activity or Fragment lifecycle, which means
that the data from the Webservice is lost when the associated UI
object's lifecycle ends. This behavior creates an undesirable user
experience.
Instead, our ViewModel delegates the data-fetching process to a new
module, a repository.
And direct answer for your question:
Even though the repository module looks unnecessary, it serves an
important purpose: it abstracts the data sources from the rest of the
app. Now, our UserProfileViewModel doesn't know how the data is
fetched, so we can provide the view model with data obtained from
several different data-fetching implementations.
Basically, you can give all work to your ViewModel, but it's not recommended.
If you work/planning to work as a dev, maintaining your code, make it flexible to change and understandable for others is also important and usually, everyone appreciates this

Does a combination of lifecycleScope and SharedFlow eliminate the need for ViewModels?

I'm diving into Kotlin Flow for the first time, and I'm wondering if with it ViewModel has a place anymore. ViewModel's advantage was that it was lifecycle aware and would automatically cancel subscriptions on the ViewModel's LiveData when the Activity gets destroyed. A Kotlin SharedFlow works similarly to LiveData in that it can be subscribed to by multiple observers. And in Kotlin a lifecycleScope coroutine should cancel all child coroutines upon the lifecycle ending. So if we had something like this:
lifecycleScope.launch(Dispatchers.IO) {
//Do something
flow.emit(result)
}
lifecycleScope.launch(Dispatchers.Main) {
flow.collect {
//Display the data
}
}
This should cancel when the lifecycle goes out of scope. Am I missing a problem here? Or is there a good reason to use ViewModels anyway? Assume here that there are no 3rd party libraries I need to interact with that expect LiveData or ViewModels.
Keeping the whole discussion aside of LiveData vs SharedFlow or StateFlow. Coming onto ViewModels as you asked. If we are to go by documentation
The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
UI controllers such as activities and fragments are primarily intended to display UI data, react to user actions, or handle operating system communication, such as permission requests. Requiring UI controllers to also be responsible for loading data from a database or network adds bloat to the class. Assigning excessive responsibility to UI controllers can result in a single class that tries to handle all of an app's work by itself, instead of delegating work to other classes. Assigning excessive responsibility to the UI controllers in this way also makes testing a lot harder.
It's easier and more efficient to separate out view data ownership from UI controller logic.
I guess this sums it up quite well. It is true that lifeCycleScope can eliminate the need of ViewModel in a way, but ViewModel does more than just being a holder for LiveData.
Even if you want to use SharedFlow or StateFlow over LiveData I would suggest you still make use of ViewModel and inside it use a viewModelScope instead to still perform the usual and required separation of concerns between UI and data.
ViewModel survives configuration changes. Activities and Fragments do not. That’s the primary purpose of ViewModel. ViewModel does not automatically cancel subscriptions to its LiveData. LiveData does that for itself independently. For that reason, the existence of SharedFlow has no impact whatsoever on the usefulness of ViewModel.
If you’re following an MVVM pattern and using ViewModel as the VM, then using SharedFlow instead of LiveData takes it a step closer to being platform agnostic and being easier to unit test.

What are the Kotlin Coroutines, How they are different from live data

I am starting to work with new things that are developed by the developer community Android, one of them is Coroutines. I have used the LiveData
and I assumed while using them, they are also lifecycle safe, then why coroutines are introduced and how they are different from LiveData. I have seen the video on Coroutines at Youtube, from developer channel, but I don't understand that completely. How Suspend and Resume works better than LiveData.
Ok first of all coroutines don't really relate too much with LiveData although they might share here and there some concepts.
Coroutines are used to perform async operation: Retreive data from network, database etc.
Coroutines can be used as "LiveData" if you are talking in the context of Channels or Flows (which I don't recomend because you will lose the lifecycle in it). With coroutines you can switch to threads easily.
Suspend functions are just functions that hold and don't run directly. Any suspending function should be inside a coroutine.
The simplest use case I can give you is this:
runBlocking{
//you are inside of a coroutine
val data = getDataFromBackground()
}
suspend fun getDataFromBackground(): SomeDataType = receiveSomeData()
The receiveSomeData method is also marked with suspend keyword.
But of course there is a lot more. The documentation is perfect way to start.
I also have a personal article about coroutines, you may find them easy there.
There is only one point I can think of that you can replace data with coroutines, and that's using Channels. The view won't be observing for LiveData but will be consuming values comming from a channel, created and shared with DI or something.
EDIT:
If you really want to use LiveData + coroutines please check this awesome library by the Android team.
Coroutines is for asynchronous job. Live Data are used to update your View (Activity & Fragment)

ObservableField or LiveData? Which one is the best?

I have been testing Livedata and AAC in general.
What is the core difference between LiveData and ObservableField?
Which one is the best and when should I use one over another?
The core difference is that ObservableField<T> is not lifecycle-aware and hence there cannot be any automatic subscription management. While LiveData<T> is lifecycle-aware and solves tons of headaches with subscription management when it comes to Activity/Fragment lifecycles.
There is no one way to answer what is the best to use. It is a personal choice, but I would suggest using LiveData<T> just to save yourself some time and avoid potential issues in the future.
Both LiveData and Observable could be used alternatively. LiveData is lifecycle aware and hence will notify only the observables which are "active".
Quoting official documentation on https://developer.android.com/topic/libraries/data-binding/architecture#livedata
Unlike objects that implement Observable—such as observable fields—LiveData objects know about the lifecycle of the observers subscribed to the data changes. This knowledge enables many benefits, which are explained in The advantages of using LiveData. In Android Studio version 3.1 and higher, you can replace observable fields with LiveData objects in your data binding code.
As mentioned both are usable for UI binding interchangeably. LiveData is a quick method but if you want more control on the binding Obserable is a way to go with.
Quoting official documentation on https://developer.android.com/topic/libraries/data-binding/architecture#observable-viewmodel
There are situations where you might prefer to use a ViewModel component that implements the Observable interface over using LiveData objects, even if you lose the lifecycle management capabilities of LiveData. Using a ViewModel component that implements Observable gives you more control over the binding adapters in your app. For example, this pattern gives you more control over the notifications when data changes, it also allows you to specify a custom method to set the value of an attribute in two-way data binding.
We get options to customize the binding in case of an Observable which might be helpful in some case.
Personal preference is to go with LiveData. In case some some customization or more control is needed on the binding go for Obervable
Similarities
Work well with data binding
Bound views automatically unsubscribe when in the background
POJO classes can also subscribe to changes
Differences
LiveData allows for POJO subscribers to be lifecycle aware. Meaning that if you have a property B that you want to update when A changes, you can opt to not receive updates when the attached view is inactive. This saves resources.
Background thread updates of ObservableField<T> are immediate. MutableLiveData.postData is delayed.
Values of LiveData<T> and ObservableField<T> are always nullable, but the primitive implementations ObservableInt, -Float, -Boolean etc are non-nullable.
MutableLiveData<T> doesn't take a constructor value to set on initialization.
When to use what
Do you have external events that may trigger cascading data change in the ViewModel when the app is in the backgrond? You should probably go for LiveData
Do you require value update on background threads to be immediate*? Use Observables
None of the above requirements? You can't go wrong with either but ObservableField is a simpler class.
*) "Immediate" in the sense that a get directly after a set/postValue is guaranteed to return the value you just set. None of the types are of course immediate when it comes to UI update.

Categories

Resources