Hello. Help me understand the fundamental difference between using remember { mutableStateOf()} and liveData(ViewModel).
This is necessary to decide which model to use for the correct operation of the UI. I understand the life cycle of data in Activiti.
My application will receive data from a library in which instances of data classes with user data are stored in memory.
And all the work of retrieving/updating data is done by this library. The same library does not destroy data when the Activity is destroyed.
And I can take this data again at any time. Of particular interest is the moment of returning to the previous
window with its previous state.
Sorry if I express myself incorrectly.
And, one more point: as I already wrote, instances of data classes are stored in memory. I should use remember { mutableStateOf(class)}
to an instance of a class, or to each of its fields, for redrawing if some field of the class has been changed?
Generally if you want Compose to update when some value is changed, something (usually a view model) needs to expose it in an object that can be observed. This could be a Kotlin Flow, an Android LiveData, or an RxJava Observable (I recommend using a Flow and Flow.collectAsState()
).
If you use mutableStateOf()
Compose won’t know if the data is changed.
I believe it’s not correct.
You definitely can use mutableStateOf() as an observable state holder for Compose, same as StateFlow,
Compose knows how to use it and will recompose when the content of MutableState<> changes, it is integrated on the runtime level
See kdoc for MutableState:
https://developer.android.com/reference/kotlin/androidx/compose/runtime/MutableState
The main difference between remember { mutableStateOf() } and having state holder (it can be also mutableStateOf(), or StateFlow, or LiveData), is that who owns state.
Remember is a state holding mechanics, which holds state on level of composable, which is fine, but usually only for UI state which you don’t want to save.
In general there are many advantages to hold it on level of VM, so you do not pollute your UI code with business logic of state handling, validation, saving etc
What to use on level of VM, depends on your taste.
I would not recommend using LiveData at all; it’s not flexible, the API is not great, and if you need anything more complex, you are stuck. I think it is softly deprecated for now.
StateFlow is the most flexible and better integrated with Kotlin solution, but another question, do you need all coroutines features or not, and specifically, do you use reactive features (mapping multiple streams, running in another thread etc)
If not, and State/MutableState from compose is good alternative, but very simple, essentially just a way to expose observable state for compose code, not usable for other cases
If you want to preserve state on Activity destroy, you have to use saved instance state integration, you can do it both from VM or from compose code
My main point was that if you use remember
like this:
val foo = remember { mutableStateOf(bar) }
then to get the composables to recompose you need foo.value = baz
somewhere in your Compose code. Compose won’t notice if one of the fields of bar
changes.
You could put a MutableState object in your view model instead of using a StateFlow, but then you’ve polluted your view model with view-specific code. A view model shouldn’t care if the UI is implemented with Compose or XML layouts.