Sebastian Redl
Sebastian Redl

Reputation: 72019

How to launch a coroutine that should never be canceled from a Compose event handler

I have this composable that represents an "edit data" screen:

@Composable
fun EditNodeScreen(
    vm: EditNodeViewModel,
    canceled: () -> Unit,
    accepted: (id: UUID) -> Unit
) {
    // ...
    Button(onClick = {
      val id = vm.save()
      accepted(id)
    }) {
      Text(text = "Save")
    }
}

Except, EditNodeViewModel.save() is actually a suspend function, so I can't just call it like that.

What I can find says that I should create a coroutine scope with rememberCoroutineScope(), then use that to launch a coroutine:

onClick = {
    coroutineScope.launch {
        val id = vm.save()
        accepted(id) // side question: do I have to switch back to Main context?
    }
}

But the documentation also says that this coroutine will be canceled if the composition is detached. I do not want to cancel the save process once it is commenced!

Is this still the right thing to do, or is there a better way? Should I use GlobalScope.launch perhaps?

Upvotes: 0

Views: 667

Answers (1)

Abhimanyu
Abhimanyu

Reputation: 14837

If you have to handle an operation that should be completed even if the user navigates away from the screen, use WorkManager.

From the Docs,

WorkManager is intended for work that is required to run reliably even if the user navigates off a screen, the app exits, or the device restarts.

Use Expedited work to start the task immediately.

Upvotes: 1

Related Questions