google / accompanist

A collection of extension libraries for Jetpack Compose
https://google.github.io/accompanist
Apache License 2.0
7.45k stars 599 forks source link

[Navigation] You cannot access the NavBackStackEntry's ViewModels after the NavBackStackEntry is destroyed. #1079

Closed gaohomway closed 2 years ago

gaohomway commented 2 years ago

Version:

    implementation 'com.google.accompanist:accompanist-navigation-material:0.24.2-alpha'
    implementation 'com.google.accompanist:accompanist-navigation-animation:0.24.2-alpha'

Navigation animation:

    val enterTransition: AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition? = {
        slideIntoContainer(AnimatedContentScope.SlideDirection.Left, tween(400))
    }
    val exitTransition: AnimatedContentScope<NavBackStackEntry>.() -> ExitTransition? = {
        slideOutOfContainer(AnimatedContentScope.SlideDirection.Left, tween(900))
    }

    val popEnterTransition: AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition? = {
        slideIntoContainer(AnimatedContentScope.SlideDirection.Right, tween(150))
    }
    val popExitTransition: AnimatedContentScope<NavBackStackEntry>.() -> ExitTransition? = {
        slideOutOfContainer(AnimatedContentScope.SlideDirection.Right, tween(400))
    }

FavoriteView.kt

@Composable
fun FavoriteView(navController: NavController) {

    val scrollBehavior = remember { TopAppBarDefaults.pinnedScrollBehavior() }

    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
        topBar = {
            TopAppBar(title = R.string.favorite, scrollBehavior = scrollBehavior) {
                navController.popBackStack()
            }
        },
        content = { FavoriteContent(navController) }
    )
}

@Composable
fun FavoriteContent(navController: NavController, viewModel : WindViewModel = viewModel()) {

    // ...
}

Error

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.feifeng, PID: 15120
    java.lang.IllegalStateException: You cannot access the NavBackStackEntry's ViewModels after the NavBackStackEntry is destroyed.
        at androidx.navigation.NavBackStackEntry.getViewModelStore(NavBackStackEntry.kt:205)
        at androidx.lifecycle.viewmodel.compose.ViewModelKt.get(ViewModel.kt:208)
        at androidx.lifecycle.viewmodel.compose.ViewModelKt.viewModel(ViewModel.kt:156)
        at com.feifeng.my.FavoriteViewKt.FavoriteContent(FavoriteView.kt:101)
        at com.feifeng.my.FavoriteViewKt$FavoriteView$2.invoke(FavoriteView.kt:44)
        at com.feifeng.my.FavoriteViewKt$FavoriteView$2.invoke(FavoriteView.kt:44)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
        at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
        at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
        at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:157)
        at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2270)
        at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2530)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3038)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3024)
        at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:252)
        at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
        at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3024)
        at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:2999)
        at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:709)
        at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:876)
        at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:107)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:485)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:454)
        at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
        at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1074)
        at android.view.Choreographer.doCallbacks(Choreographer.java:897)
        at android.view.Choreographer.doFrame(Choreographer.java:822)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1061)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:236)
        at android.app.ActivityThread.main(ActivityThread.java:8060)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
D/OOMEventManagerFK: checkEventAndDumpForJE: 0
I/Process: Sending signal. PID: 15120 SIG: 9

Is it a problem of use, or a problem of Navigation?

lutobler commented 2 years ago

I have the same problem. For me this occurs when navigating between two components using the bottom bar, and both components use their route's BackStackEntry as a ViewModelStoreOwner. It occurs for me when tapping back and forth between the views quite fast, so when the transition animation is still running.

trevjonez commented 2 years ago

Seem that the likely root cause is with the integration between the androidx navigation and lifecycle libraries.

https://issuetracker.google.com/issues/228865698

josh-Muleshi commented 2 years ago

can you change the NavController to NavHostController ?

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

svenjacobs commented 1 year ago

I got the same crash in Crashlytics from a customer but cannot reproduce it. Is there a fix for this?

Stacktrace:

Fatal Exception: java.lang.IllegalStateException: You cannot access the NavBackStackEntry's ViewModels after the NavBackStackEntry is destroyed.
       at androidx.navigation.NavBackStackEntry.getViewModelStore(NavBackStackEntry.kt:202)
       at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:142)
       at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:89)
       at xxx.app.main.view.MainScreenKt.Content(MainScreen.kt:319)
       at xxx.app.main.view.MainScreenKt.access$Content(MainScreen.kt:1)
       at xxx.app.main.view.MainScreenKt$MainScreen$5$1$1$1.invoke(MainScreen.kt:260)
       at xxx.app.main.view.MainScreenKt$MainScreen$5$1$1$1.invoke(MainScreen.kt:259)
       at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
       at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
       at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.java:145)
       at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2375)
       at androidx.compose.runtime.ComposerImpl.skipToGroupEnd(Composer.kt:2666)
       at xxx.core.common.compose.components.layout.ContentLoadingLayoutKt.ContentLoadingLayout-H8av0Xo(ContentLoadingLayout.kt:69)
       at xxx.app.main.view.MainScreenKt$MainScreen$5$1.invoke(MainScreen.kt:254)
       at xxx.app.main.view.MainScreenKt$MainScreen$5$1.invoke(MainScreen.kt:248)
       at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
       at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
       at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.java:145)
       at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2375)
       at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(ComposerImpl.java:2643)
       at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3260)
       at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3238)
       at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(SnapshotStateKt__DerivedStateKt.java:341)
       at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(SnapshotStateKt.java:1)
       at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3238)
       at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3203)
       at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:771)
       at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1031)
       at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:125)
       at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:534)
       at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:503)
       at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
       at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.java:109)
       at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.java:41)
       at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1008)
       at android.view.Choreographer.doCallbacks(Choreographer.java:809)
       at android.view.Choreographer.doFrame(Choreographer.java:740)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:995)
       at android.os.Handler.handleCallback(Handler.java:938)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:246)
       at android.app.ActivityThread.main(ActivityThread.java:8633)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)

Compose: 1.3.1 (BOM 2023.01.00) Accompanist: 0.28.0 Jetpack Navigation: 2.5.3

TheNephilim88 commented 1 year ago

Same here, but still cant reproduce on my own :(

James-Aidoo commented 1 year ago

Same here. Reproducing it is the problem. Seems impossible

Minoro75 commented 1 year ago

after setting animation duration scale in Developer Options of device - crash reproduces every time.