Status Update
Comments
il...@google.com <il...@google.com>
mg...@google.com <mg...@google.com>
ap...@google.com <ap...@google.com> #2
Branch: androidx-main
commit 119ebbfcde3fe65ac338296277a839c20170989a
Author: Marcello Galhardo <mgalhardo@google.com>
Date: Wed Jan 31 17:10:10 2024
Add `dropUnlessStateIsAtLeast` callback wrappers for Compose
* Adds `dropUnlessResumed` and `dropUnlessStarted` callback wrappers for Compose.
* These wrappers safe guard callbacks (e.g. `onClick: () -> Unit`) and ensure they only run when the lifecycle is in a valid state, such as `State.RESUMED`.
RelNote: "`whenLifecycle` API has been
added to safeguard callbacks against a `Lifecycle.State`, when the callback may triggered while a composable is running. For example: `onClick: () -> Unit = dropUnlessResumed { navController.navigate(NEW_SCREEN) }`"
Test: DropUnlessLifecycleTest
Bug: 317230685
Change-Id: Icba837aeb90426b00bc5888e663f775284191fe2
M lifecycle/lifecycle-runtime-compose/api/current.txt
M lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
A lifecycle/lifecycle-runtime-compose/samples/src/main/java/androidx/lifecycle/compose/samples/DropUnlessLifecycleSamples.kt
A lifecycle/lifecycle-runtime-compose/src/androidTest/java/androidx/lifecycle/compose/DropUnlessLifecycleTest.kt
A lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/DropUnlessLifecycle.kt
il...@google.com <il...@google.com>
pr...@google.com <pr...@google.com> #3
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.lifecycle:lifecycle-runtime-compose:2.8.0-alpha02
he...@reaktor.com <he...@reaktor.com> #4
Thanks for adding dropUnlessResumed()
, it's perfect for preventing accidental navController.popBackStack()
invocations. What it fails to handle though, is when the wrapped callback takes an argument. I believe this is a common practice as it's recommended not to pass the NavController
to the composables, but offer callbacks that perform the actual navigation.
It's also bit unfortunate that the function is @Composable
as it makes it impossible to call it from these callbacks. But it does make it more ergonomic to call, especially since you need to be very careful to use the correct LifecycleOwner
.
Am I misinterpreting the use of this API by using it close to the navigation component? Or should I wrap the user interactions instead, such as Button.onClick
, where the callbacks share the () -> Unit
signature?
il...@google.com <il...@google.com> #5
Re
Am I misinterpreting the use of this API by using it close to the navigation component? Or should I wrap the user interactions instead, such as Button.onClick, where the callbacks share the () -> Unit signature?
You should be wrapping the user interaction side, yes.
ha...@gmail.com <ha...@gmail.com> #6
I am curious - is there a difference to checking currentBackStackEntry.lifecycle.currentState
instead? This way we don't need to be in a composable context, which seems like a more flexible solution.
Description
When using Compose navigation, calls to navigate should be guarded by lifecycle state to prevent invoking navigation methods while composable is transitioning as an effect of navigation. Given navigation destination:
navigation calls should be guarded by
backStackEntry
lifecycle state to prevent invoking navigation from composable that's under transition:It would be really useful to have a set of lifecycle aware function wrappers for guarding execution of calls, for example:
or standalone composable version which will use
LocalLifecycleOwner
to access lifecycle state: