https://kotlinlang.org logo
#compose
Title
# compose
k

krzysztof

02/01/2021, 8:40 PM
Say I have a data class with two properties - one that is declared in primary constructor, one as “normal” property. A
livedata
of said data class was part of state in my view model. I started to observe it as state. What I found out is, I believe, is an optimisation that compose is applying, but correct me if I’m wrong here. When I
postValue
with a new data class, with changed property that is declared in primary constructor,
compose
catches that and triggers recomposition on state - so that’s correct. Now,
postValue
with my data class with a change to a property that was not part of the primary constructor -
compose
does not trigger recomposition, even if observer in
observeAsState
is triggered.
So I think compose is comparing both values using either
hash
or
equality
check, to consider if they’re equal
And with
data class
, properties that are not part of primary constructor do not take in hash generation or equality comparison
m

Michael Elgavi

02/01/2021, 9:08 PM
Looked into this recently.
observeAsState
uses the default form of
mutableStateOf
, which uses
structuralEqualityPolicy()
to compare new states with old states:
Copy code
fun <T> mutableStateOf(
    value: T,
    policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
): MutableState<T> = SnapshotMutableState(value, policy)
Digging further,
StructuralEqualityPolicy
is implemented like this:
Copy code
private object StructuralEqualityPolicy : SnapshotMutationPolicy<Any?> {
    override fun equivalent(a: Any?, b: Any?) = a == b
}
So your theory is correct, it's an
equals
check.
You could make your own
observeAsState
that uses a different equality policy, like
neverEqualPolicy()
if that's what you're looking for.
k

krzysztof

02/02/2021, 7:28 AM
Nice breakdown. Checked the code myself now and it answer my question, thanks!
5 Views