Originally published on Medium:
https://medium.com/@supsabhi/the-beginners-guide-to-state-collection-in-jetpack-compose-92662afe3e44?sharedUserId=supsabhi
How to Collect State in Jetpack Compose Without Draining the Battery?
In the journey of learning Jetpack Compose, you’ve likely encountered a common challenge: How to get my data from my ViewModel into my UI?
In the world of Android, we usually use Flow to stream data. But Compose speaks “State.” To bridge that gap, we use two popular tools: collectAsState() and collectAsStateWithLifecycle().
collectAsState() and collectAsStateWithLifecycle() both listen to a Flow (or StateFlow) from your ViewModel and turn it into Compose State so your UI can automatically recompose.
While they look almost identical, choosing the wrong one can lead to resource leaks or unexpected behavior of an app. Let’s break them down in a simple real world way.
What collectAsState() does
Think of collectAsState() as a loyal friend who never stops listening to you. As soon as your Composable is on the screen, it starts “collecting” data from your Flow and turning it into a State object that Compose can read.It stops collecting when the composable leaves the composition (when you navigate away or the composable is removed).
The Catch: This friend is too loyal. If the user minimizes your app to check a text message, collectAsState() keeps listening to that data stream in the background.
Pros: Simple, built into the core Compose library.
Cons: It keeps the “pipe” open even when the user can’t see the app.your Flow keeps emitting and your ViewModel keeps doing work,which drains the battery and consumes resources unnecessarily.
How to use collectAsState()
You don’t need any extra lifecycle libraries for this one, as it comes built-in with the standard Compose runtime.
@Composable
fun UserProfile(viewModel: MyViewModel)
{
val uiState by viewModel.userFlow.collectAsState()
Text(text = "Hello, ${uiState.name}")
}
What collectAsStateWithLifecycle() adds
This is the “Android-aware” version of the collector. collectAsStateWithLifecycle() behaves like collectAsState(), but also respects the Android lifecycle of the screen/activity.It doesn’t just listen blindly; it watches the Lifecycle of your app.
When the user moves away from the app (putting it in the background), collectAsStateWithLifecycle() says, “Since nobody is looking at the screen, I’m going to stop collecting for a bit to save energy.” As soon as the user comes back, it picks right up where it left off.
This means less wasted work, fewer unnecessary emissions, and safer behavior during configuration changes and navigation.
Why this matters: If your Flow is connected to a database or a location sensor, keeping it active in the background is a silent performance killer.
How to use it in your code
To use the lifecycle-aware version, make sure you have the lifecycle-runtime-compose dependency in your build.gradle file. Then, it’s as simple as this:
@Composable
fun UserProfile(viewModel: MyViewModel)
{
val uiState by viewModel.userFlow.collectAsStateWithLifecycle()
Text(text = "Hello, ${uiState.name}")
}
Final Thoughts
So basically we can say that the big difference between two of them is that collectAsStateWithLifecycle() is lifecycle-aware at the Android level, while collectAsState() only follows the composable’s own lifecycle, which can waste resources when the app goes to the background.
You can think of it this way:
“I want my screen to stay in sync with the Flow only while the user can actually see it.”
That sentence describes collectAsStateWithLifecycle() almost perfectly.
👏 Found this helpful?
Are you still using the standard collectAsState() in your Android projects, or have you already made the switch to the lifecycle-aware version?
If you found this helpful, hit the 👏 clap button and follow for more beginner-friendly Jetpack Compose tips!💬 Questions or suggestions? Drop a comment below — I read and respond to every one!
🔄 Share this article with fellow Android developers who might find it useful.
Happy coding! 🚀
Top comments (0)