Reputation: 317
I have a view model that processes an array of bytes into a somewhat complex array of floats. Part of the data is a timestamp which I've setup as a LiveData type and the observer listens for changes in the timestamp. When a change happens, it gets the new timestamp and also gets the array of floats.
My question is when "value" is set in a LiveData object, are the observers immediately called or does it wait for the surrounding function to complete? In other words, should I make sure to update whatever other data the observer is accessing before setting the "value"?
Also, is this abusing the LiveData mechanism (using it as a flag for a larger change in data)?
val mTime = MutableLiveData<Double>()
var mStateDataSet = ArrayList<ArrayList<Float>>()
fun updateData(rawData: ByteArray) {
val buffer = ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN)
val min = (buffer.getInt(4)).toDouble()
val usec = (buffer.getInt(8)).toDouble()
val time: Double = min * 60.0 + usec * (1.0 / 1e6)
// Update the live data....
mTime.value = time
// This data is used by the observer of "mTime"
mStateDataSet[KEY_VOLTAGES] = getSubDataFloat(buffer, NUM_VOLTAGE);
mStateDataSet[KEY_PRESSURES] = getSubDataFloat(buffer, NUM_PRESSURE);
mStateDataSet[KEY_LEFT_ANGLES] = getSubDataFloat(buffer, NUM_LEFT_ANGLES);
mStateDataSet[KEY_RIGHT_ANGLES] = getSubDataFloat(buffer, NUM_RIGHT_ANGLES);
mStateDataSet[KEY_LEFT_ACCEL] = getSubDataFloat(buffer, NUM_LEFT_ACCEL);
mStateDataSet[KEY_RIGHT_ACCEL] = getSubDataFloat(buffer, NUM_RIGHT_ACCEL);
mStateDataSet[KEY_DEBUG] = getSubDataFloat(buffer, NUM_DEBUG);
}
// Example observer from one of my fragments
val timeObserver = Observer<Double> { newTime ->
addDataPoint(mSharedStateDataViewModel.mStateDataSet, newTime)
}
mSharedStateDataViewModel.mTime.observe(viewLifecycleOwner, timeObserver)
Upvotes: 2
Views: 1044
Reputation: 119
You should update the livedata value with
mTime.postValue(time)
Also, by Tenfour04 comment
postValue
will result in the observers being called after this function returns.setValue
results in the observers being called beforesetValue
returns, so before the rest of the code in this function.
Upvotes: 3
Reputation: 8315
Given that the state of the observer's LifeCycleOwner(ie. Activity, Fragment) is at least STARTED and you use the setValue
method
, the Observer
will be notified instantly.
In your case when you do mTime.value = time
, this will instantly inform the associated Observer
, please note that if you have multiple Observers on the same LiveData
object
then it may take some time to inform all of them and there may be significant delay between notifications to two different Observers.
If however you use postValue
in your example then the Observer
will be notified after the enclosing method finishes.
Upvotes: 0