A deep dive into LocalResources.current vs LocalContext.current

If you have updated your Jetpack Compose Bill of Materials (BOM) recently to 2026.01.00 or newer you may have noticed a new lint error, LocalContextGetResourceValueCall, in Android Studio.

So what is this about?
It is about context and responding to configuration changes.
When fetching resources in Jetpack Compose we have a few options:
- stringResource(stringRes)
- LocalContext.current.getString(stringRes)
- LocalResources.current.getString(stringRes)
You can use them like this:
https://medium.com/media/16b0e8643d4536a31bfab63ffa9a68d6/href
stringResource is usually the one that you should reach for, it is the most straight forward and self documenting call and does not require you to fetch the current context or resources object prior to calling. But it has a problem, it is a Composable. This means if you want to use a resource in a lambda function such as an onClick or remember or other non-Composable you can’t — because it can only be called within a Composable.
Note — throughout this article I am using string resources as an example, but all of this applies to any type of app resource
So, let’s assume we have a helper class, WelcomeFormatter, it will format a message from a string resource and a passed in value (note — I have chosen this example over an onClick or remember example as the execution path is easier to see but the principle is the same).
https://medium.com/media/795751fb8ec13da608a0b8ba297713d9/href
In the above, we can’t use stringResource because it is not a Composable — there is no @Composable annotation. Now, we could just add the annotation, but for this example let’s pretend there is something else preventing it or we don’t want to.
So, instead, we can use getString to fetch the resource within the class using a context set up outside of the helper class.
https://medium.com/media/953f4b4981c54b9f72596fea51d22373/href
But which method to use? We often need the activity Context for other methods within our composables, such as launching an activity or showing a toast message, so why not just reuse that?
https://medium.com/media/1cda0d8b36aca4d18c63e1444547153d/href
But, this now gives a lint error because we’re reading from LocalContext.current!
This is because the LocalContext won’t necessarily change when the device configuration changes (like locale or dark mode), meaning you may get the wrong resource for the state the device is in.
So what we need to use is LocalResources.current:
https://medium.com/media/ef7cb886ea63ce9621d4914e408dc70b/href
We don’t get the lint error here as LocalResources.current is explicitly tracked by the Compose runtime.
When the device configuration changes, the Compose framework invalidates the provider for LocalResources. This triggers a recomposition for any Composable that reads this value.
While the Context object identity might remain the same, the Resources instance provided by LocalResources.current acts as a state dependency. By using it, you are effectively “subscribing” your Composable to configuration changes.
We can see this in a simple example — I am using a foldable emulator with the app in split screen with the settings app so that we know operating system is not closing and restarting the activity in the background:

I mentioned before about onClick and other similar lambdas. Do they show the same effect? They do and they don’t — it depends when the lambda is evaluated. In the case of buttons, onClick lambdas are evaluated when the click happens. So the LocalContext.current and LocalResources.current are evaluated then and the string fetched for the current configuration:

https://medium.com/media/509246b4ce459bf18ef9e062cada4bac/href
As we can see here, as stringResource responds immediately to the locale change (under the hood it uses LocalResources.current) and when each button is clicked they both respond with the correct string in the toast message.
So, for a lazily executed lambda, it doesn’t really matter whether you use LocalContext.current or LocalResources.current, they will behave the same. You will still get the lint error though as the linter isn’t able to tell when the code will be executed. So best to use LocalResources.current just in case.
Wrapping this up, it pays to take notice of any new lint rule. They have been added for a reason and will usually highlight where you can improve the readability of your code and prevent bugs from occurring.

If you want to see these simple examples in action, in the jc-text module of my Github repository.
Experiments/jc-text at main · KatieBarnett/Experiments
Jetpack Compose: Why you shouldn’t use LocalContext for Strings was originally published in ProAndroidDev on Medium, where people are continuing the conversation by highlighting and responding to this story.




This Post Has 0 Comments