One Off the Slack: Why is resources() So Strange?
Dmitry Suzdalev asked:
I’m curious why is
LocalConfiguration.current
present in the Compose’sresources()
. Does it have the effect of recomposing whenConfiguration
changes?
@Composable
@ReadOnlyComposable
private fun resources(): Resources {
LocalConfiguration.current
return LocalContext.current.resources
}
As Google’s Zach Klippenstein points out, that is exactly the reason:
Yea, this is a weird case because of the way the underlying state can change.
resources
can change out from under us whenever a config change happens, but theContext
itself doesn’t change, so we have to explicitly observe the configuration object to know when the resources might have changed.
…this implementation detail is to ensure that callers of this resources() function are restarted whenever the resources might have changed, which is standard behavior for composable functions – they restart when state they consume is changed.
In this case, “explicitly observe” means “reference”. Compose knows to watch
for changes in configuration locals and recompose, but it will only do so when
we reference the affected configuration local in a composable. LocalContext.current
is not changing, but LocalConfiguration.current
is changing, when there is a
configuration change.
If Configuration
had a getResources()
method, then we could do:
@Composable
@ReadOnlyComposable
private fun resources(): Resources {
return LocalConfiguration.current.resources
}
That would look a lot less weird. However, Configuration
does not offer getResources()
;
only Context
does. So, we need to reference LocalConfiguration.current
even
though we do not use LocalConfiguration.current
. IOW, this is a Compose workaround
for an odd bit of framework behavior.
Read the original thread in the kotlinlang Slack workspace. Not a member? Join that Slack workspace here!