google / accompanist

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

[Navigation Animation] Crash when updating from 0.29.1-alpha to 0.29.2-rc #1544

Closed joseffilzmaier closed 1 year ago

joseffilzmaier commented 1 year ago

Description

After upgrading to 0.29.2-rc i now get the crash shown below.

Steps to reproduce

I am using a AnimatedNavHost that hosts another AnimatedNavHost as one of its tabs (Material3 NavigationBar) The crash happens when calling navcontroller.navigate(...) on the outer navhostcontroller with the route that is currently the destination twice. The crash seems to be happening in the code of the inner AnimatedNavHost. The first time i visit the route the crash never occurs. The second time this route is visited, it always occurs.

If this behavior is not reproducible on your side i can try to create a minimal example showcasing the bug if necessary.

Expected behavior

The app should not crash, as it was the case with 0.29.1-alpha

Additional context

java.lang.IllegalStateException: ViewModelStore should be set before setGraph call
    at androidx.navigation.NavController.setViewModelStore(NavController.kt:2359)
    at androidx.navigation.NavHostController.setViewModelStore(NavHostController.kt:101)
    at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:142)
    at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:89)
    at <my-package>.ui.navigation.SettingsNavigationKt>.SettingsNavHost(SettingsNavigation.kt:103)
    at <my-package>.ui.navigation.SettingsNavigationKt.SettingsRoute(SettingsNavigation.kt:176)
    at <my-package>.ui.navigation.MainNavigationKt$settingsScreen$1.invoke(MainNavigation.kt:472)
    at <my-package>.ui.navigation.MainNavigationKt$settingsScreen$1.invoke(MainNavigation.kt:471)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9$1.invoke(AnimatedNavHost.kt:225)
    at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9$1.invoke(AnimatedNavHost.kt:223)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.compose.runtime.saveable.SaveableStateHolderImpl.SaveableStateProvider(SaveableStateHolder.kt:84)
    at androidx.navigation.compose.NavBackStackEntryProviderKt.SaveableStateProvider(NavBackStackEntryProvider.kt:65)
    at androidx.navigation.compose.NavBackStackEntryProviderKt.access$SaveableStateProvider(NavBackStackEntryProvider.kt:1)
    at androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke(NavBackStackEntryProvider.kt:52)
    at androidx.navigation.compose.NavBackStackEntryProviderKt$LocalOwnersProvider$1.invoke(NavBackStackEntryProvider.kt:51)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228)
    at androidx.navigation.compose.NavBackStackEntryProviderKt.LocalOwnersProvider(NavBackStackEntryProvider.kt:47)
    at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9.invoke(AnimatedNavHost.kt:223)
    at com.google.accompanist.navigation.animation.AnimatedNavHostKt$AnimatedNavHost$9.invoke(AnimatedNavHost.kt:211)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:135)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.animation.AnimatedContentKt$AnimatedContent$7$1$4.invoke(AnimatedContent.kt:701)
    at androidx.compose.animation.AnimatedContentKt$AnimatedContent$7$1$4.invoke(AnimatedContent.kt:691)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.animation.AnimatedVisibilityKt.AnimatedEnterExitImpl(AnimatedVisibility.kt:939)
    at androidx.compose.animation.AnimatedVisibilityKt.AnimatedVisibility(AnimatedVisibility.kt:607)
    at androidx.compose.animation.AnimatedContentKt$AnimatedContent$7$1.invoke(AnimatedContent.kt:681)
    at androidx.compose.animation.AnimatedContentKt$AnimatedContent$7$1.invoke(AnimatedContent.kt:664)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107)
    at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34)
    at androidx.compose.animation.AnimatedContentKt.AnimatedContent(AnimatedContent.kt:714)
    at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:196)
    at com.google.accompanist.navigation.animation.AnimatedNavHostKt.AnimatedNavHost(AnimatedNavHost.kt:89)
    at <my-package>.core.ui.NavigationAnimationKt.FadeAnimatedNavHost(NavigationAnimation.kt:90)
    at <my-package>.center.ui.navigation.MainNavigationKt$MainNavigation$1$2.invoke(MainNavigation.kt:254)
    at <my-package>.center.ui.navigation.MainNavigationKt$MainNavigation$1$2.invoke(MainNavigation.kt:253)
    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:162)
    at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2465)
    at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2733)
    at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3364)
    at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3342)
    at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341)
    at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1)
    at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3342)
    at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3307)
    at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:772)
    at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:1047)
    at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:124)
    at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:541)
    at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:510)
    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:1229)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
    at android.view.Choreographer.doCallbacks(Choreographer.java:899)
    at android.view.Choreographer.doFrame(Choreographer.java:827)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7884)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
    Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock@2b89469, androidx.compose.ui.platform.MotionDurationScaleImpl@8055eee, StandaloneCoroutine{Cancelling}@74a1f8f, AndroidUiDispatcher@7c7321c]
ianhanniballake commented 1 year ago

I am using a AnimatedNavHost that hosts another AnimatedNavHost as one of its tabs (Material3 NavigationBar)

This is generally always the wrong way to do things, but we shouldn't crash in any case.

If this behavior is not reproducible on your side i can try to create a minimal example showcasing the bug if necessary.

Yes, this would be really helpful - ideally a repository that we can run to reproduce it directly.

joseffilzmaier commented 1 year ago

I have created a minimal example showcasing the bug:

https://github.com/joseffilzmaier/accompanistIssue1544Demo

You can trigger the crash by pressing on the "second" tab in the bottom NavigationBar twice.

I do use nested NavHost's as i want to share a toolbar between all the screens. Also the "second" screen has a different layout depending on the available screen space (resizable on Desktop). I don't see a way to achieve this by using nested navigation. I have already read quite a few articles about navigation and nested navigation, but i could not find a way to achieve what i wanted without nesting NavHost {}s. If you have any further insights i would appreciate any hints on how to achieve such a thing :).

github-actions[bot] commented 1 year 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.

claraf3 commented 1 year ago

The issue is fixed in the accompanist navigation-animation 0.31.3-beta.

Alternatively, latest accompanist navigation-animation has been migrated back into androidx base navigation available in navigation 2.7.0-alpha01.