#compose
Title
# compose
s

Stylianos Gakis

04/15/2024, 7:39 AM
With the new lifecycle effects, I wanted to do something similar to starting a coroutine with repeatOnLifecycle, so that it pauses itself when the effect ends and so on. It looks like those APIs do not give us a coroutine scope in there which is cancelled automatically, not sure if there is a way to use those for this use case or if I should really just use a LaunchedEffect with repeatOnLifecycle as normal instead. I think I got something like this now
Copy code
LifecycleStartEffect(Unit) {
  val job = this.lifecycleScope.launch { ... }
  onStopOrDispose {
    job.cancel()
  }
}
But might as well just do this instead?
Copy code
val lifecycle = LocalLifecycleOwner.current.lifecycle
LaunchedEffect(lifecycle) {
  lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
    ...
  }
}
Something else I may be missing here instead? 👀
➕ 1
Or hmm maybe I could do
Copy code
LifecycleStartEffect(Unit) {
  val job = this.lifecycleScope.launch { 
    this.repeatOnLifecycle(Lifecycle.State.STARTED) {
      ...
    }
  }
  onStopOrDispose {
  }
}
But that looks a bit awkward both with the empty dispose block and with having to specify the state level the repeatOnLifecycle should be following 😄
m

Magnus Gudmandsen

04/15/2024, 9:08 AM
For the record, we had similar issues when trying to use this for navigation events (to make sure they only triggered in
Started
state), especially when working with bottom sheets and results that should trigger navigation to elsewhere. It seems that this effect takes a while until the lifecycles are set again, so we get a race condition on handling the result, since the old coroutine that handled the navigation previously was cancelled. Reading your post again... aren't we having opposite issues here?
s

Stylianos Gakis

04/15/2024, 9:11 AM
For your use case it sounds like what you should reach for is this https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:lifecycl[…]pose/DropUnlessLifecycle.kt;l=78-83?q=drop%20when%20lifecycle instead right? FWIW Ours doesn’t have something to do with nav, just wanted to see if I could reach for these new APIs in order to ensure that I am running a coroutine only when the app is at least on Started.
m

Magnus Gudmandsen

04/15/2024, 9:15 AM
I think the LifecycleStartEvent sounds like a better fit, since I actually need a CoroutineScope to observe my event flow that triggers the navigation, otherwise I would need to do something like
Copy code
dropUnlessStarted {
    LaunchedEffect(Unit) {
        navigationEvents.collectLatest { navigate(it) }
    }
}
Which feels a bit awkward...
s

Stylianos Gakis

04/15/2024, 9:18 AM
What I had in mind with that is to do something like
Copy code
SomeScreen(
  onNavigateToX = dropUnlessStarted { navController.navigateToX() }
)
Inside your screen you can observe that effect in whichever way you want. Then the lambda that you call can be this one, which will ensure it will only try to do the navigation when you are at least Started. But with that said, if it is an event coming not from a user interaction, you probably do not want to drop it, since you will then leave it unconsumed as well. This however fits very well for normal “button clicked -> run this” scenarios. Where it’s ok to drop the event if for example someone clicked on a button twice really fast
👍 1
m

Magnus Gudmandsen

04/15/2024, 9:23 AM
I see, yes, that would make sense. In our case we have a navigation handler wrapper that works for all sort of flows, but perhaps it shouldn't be lifecycle aware so it doesn't miss events, but rather the event triggers should be (when user triggered) 👍
i

Ian Lake

04/15/2024, 2:38 PM
You should use repeatOnLifecycle in LaunchedEffect, see https://issuetracker.google.com/issues/316073977#comment5
👍 1
s

Stylianos Gakis

04/15/2024, 3:23 PM
Yup that’s what I ended up doing myself too, since I felt like I am making it less readable (and error prone) instead of improving it. Glad to hear that it seems to be the recommended approach going forward. Thanks Ian!
70 Views