Android Engineers

Android Engineers

Share this post

Android Engineers
Android Engineers
Difference between remember and rememberSaveable

Difference between remember and rememberSaveable

with examples

Akshay Nandwana's avatar
Akshay Nandwana
Jul 29, 2024
1

Share this post

Android Engineers
Android Engineers
Difference between remember and rememberSaveable
Share

State management is a cornerstone of dynamic UIs in Jetpack Compose. Among its many tools, remember and rememberSaveable are commonly used to manage state inside composable functions. Although they may appear similar, their behavior differs significantly when it comes to state persistence during lifecycle changes like screen rotations or process recreation.

Let’s explore these differences with practical examples and learn about advanced use cases such as using Bundle and custom Saver.


Jetpack Compose Cohort - Starting May 1


1. What is remember?

The remember function helps store a value in memory across recompositions. However, it does not persist the state during configuration changes, such as screen rotation or process recreation.

Example 1: Using remember

Imagine you’re building a simple counter app:

@Composable
fun CounterWithRemember() {
    var count by remember { mutableStateOf(0) }

    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Count: $count")
        Button(onClick = { count++ }) {
            Text("Increment")
        }
    }
}

Here, the counter value resets to 0 when you rotate the device because remember only retains the state during the current composition lifecycle.

2. What is rememberSaveable?

rememberSaveable is an extension of remember that retains the state across configuration changes by saving it into a Bundle, which is part of Android’s saved instance state mechanism.

Example 2: Using rememberSaveable

Let’s enhance our counter app to retain its value even after a screen rotation:

@Composable
fun CounterWithRememberSaveable() {
    var count by rememberSaveable { mutableStateOf(0) }

    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Count: $count")
        Button(onClick = { count++ }) {
            Text("Increment")
        }
    }
}

In this case, the counter value persists even if the screen is rotated because the value is saved into a Bundle and restored automatically.

3. Can We Use ViewModel for State Persistence?

Yes, you can! If the state is more complex or needs to be shared across multiple composables, using a ViewModel is often a better approach. Unlike rememberSaveable, a ViewModel persists state across configuration changes and process recreation as long as the app is not explicitly killed.

Example: Using ViewModel

class CounterViewModel : ViewModel() {
    var count by mutableStateOf(0)
        private set

    fun increment() {
        count++
    }
}
@Composable
fun CounterWithViewModel(viewModel: CounterViewModel = viewModel()) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Count: ${viewModel.count}")
        Button(onClick = { viewModel.increment() }) {
            Text("Increment")
        }
    }
}

Here, CounterViewModel retains the counter state even if the system kills and recreates the activity.

4. What About Complex Objects?

rememberSaveable can handle basic data types like String, Int, or Boolean because they are serializable and can be stored in a Bundle. However, for custom or non-primitive data types, you need to use a Saver.

5. What is a Saver?

A Saver helps rememberSaveable store and restore complex objects by converting them into a format that can be saved into a Bundle (e.g., a Map or List).

Steps to Create a Custom Saver:

  1. Define the Object You Want to Save:
    Create a data class or object for your state.

  2. Implement a Saver:
    Write a Saver that converts the object into a savable format and restores it when needed.

  3. Use the Saver in rememberSaveable:
    Pass the Saver to rememberSaveable manage your custom object’s state.

Example: Saving a Custom User Object

data class User(val name: String, val age: Int)

val UserSaver = Saver<User, Map<String, Any>>(
    save = { mapOf("name" to it.name, "age" to it.age) },
    restore = { User(it["name"] as String, it["age"] as Int) }
)

@Composable
fun CustomSaverExample() {
    var user by rememberSaveable(stateSaver = UserSaver) {
        mutableStateOf(User(name = "Akshay", age = 28))
    }

    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Name: ${user.name}, Age: ${user.age}")
        Button(onClick = { user = user.copy(age = user.age + 1) })  
        { Text("Increase Age") }
     }
}

Here, the User object is saved into a Map (compatible with a Bundle) and restored when needed.

Conclusion

To summarize:

  • Use remember for transient state that doesn’t need to persist across configuration changes.

  • Use rememberSaveable for state that needs to survive configuration changes, leveraging Bundles.

  • Use ViewModel for complex state management or shared state across composables.

  • Create a Saver for non-primitive objects when using rememberSaveable.

By combining these tools, you can effectively manage the state in your Jetpack Compose applications, ensuring a smooth and robust user experience.


Akshay Nandwana
Founder AndroidEngineers

You can connect with me on:

  • Twitter

  • LinkedIn

  • YouTube

  • Instagram

Book 1:1 Session here Click Here

Join our classes
https://www.androidengineers.in/courses

1

Share this post

Android Engineers
Android Engineers
Difference between remember and rememberSaveable
Share
© 2025 Akshay Nandwana
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share