Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Navigation Material] App crashes on launch #1175

Closed
tkirshboim opened this issue May 25, 2022 · 8 comments
Closed

[Navigation Material] App crashes on launch #1175

tkirshboim opened this issue May 25, 2022 · 8 comments
Assignees

Comments

@tkirshboim
Copy link

tkirshboim commented May 25, 2022

Description

I am seeing a crash when using the navigation material components of the Accompanist library. Here's a repository with code that produces the crash.

Click to see the code that produces that crash
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val stateChangeEnabled = remember { mutableStateOf(false) }
            val sheetState = rememberModalBottomSheetState(stateChangeEnabled)
            val bottomSheetNavigator = remember(sheetState) { BottomSheetNavigator(sheetState) }
            val navController = rememberNavController(bottomSheetNavigator)
            val backStackEntry =
                with(navController) { currentBackStackEntryFlow.collectAsState(currentBackStackEntry) }
            LaunchedEffect(backStackEntry.value) { stateChangeEnabled.value = false }

            ModalBottomSheetLayout(bottomSheetNavigator) {
                NavHost(navController = navController, startDestination = "xyz") {
                    composable("xyz") {}
                }
            }
        }
    }
}

// Inline this function to work around the crash.
@Composable
private fun rememberModalBottomSheetState(stateChangeEnabled: MutableState<Boolean>) =
    rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Hidden,
        confirmStateChange = { stateChangeEnabled.value }
    )
Click to see the crash stack trace
E: FATAL EXCEPTION: main
    Process: com.kirshboim.accompanist.crash, PID: 5252
    java.util.NoSuchElementException: List contains no element matching the predicate.
        at androidx.navigation.compose.NavHostKt$NavHost$4.invoke(NavHost.kt:180)
        at androidx.navigation.compose.NavHostKt$NavHost$4.invoke(NavHost.kt:141)
        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.CrossfadeKt$Crossfade$4$1.invoke(Crossfade.kt:115)
        at androidx.compose.animation.CrossfadeKt$Crossfade$4$1.invoke(Crossfade.kt:110)
        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.CrossfadeKt.Crossfade(Crossfade.kt:124)
        at androidx.compose.animation.CrossfadeKt.Crossfade(Crossfade.kt:55)
        at androidx.navigation.compose.NavHostKt.NavHost(NavHost.kt:141)
        at androidx.navigation.compose.NavHostKt.NavHost(NavHost.kt:67)
        at com.kirshboim.accompanist.crash.ComposableSingletons$MainActivityKt$lambda-2$1$2.invoke(MainActivity.kt:37)
        at com.kirshboim.accompanist.crash.ComposableSingletons$MainActivityKt$lambda-2$1$2.invoke(MainActivity.kt:36)
        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.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:330)
        at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:326)
        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:142)
        at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2350)
        at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2610)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3196)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3174)
        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:3174)
        at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:3140)
        at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:722)
        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:1035)
        at android.view.Choreographer.doCallbacks(Choreographer.java:845)
        at android.view.Choreographer.doFrame(Choreographer.java:775)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
E:     at android.os.Handler.handleCallback(Handler.java:938)
        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:7842)
        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:1003)
    	Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock@5d1a14c, androidx.compose.ui.platform.MotionDurationScaleImpl@62f0595, StandaloneCoroutine{Cancelling}@bf6f6aa, AndroidUiDispatcher@8cb029b]

I'm using the following library versions:

accompanist_version = '0.24.9-beta'
compose_version = '1.2.0-beta02'
material_version = '1.2.0-beta02'
nav_version = '2.5.0-rc01'

Steps to reproduce

  1. Check out the repository I set up that demonstrates the crash: https://github.com/tkirshboim/accompanist-navigation-crash
  2. Open the project in Android Studio (I used Chipmunk 2021.2.1), build and run the app (I ran it on an Android 12 emulator).

Expected behavior

The app does not crash.

Additional context

#1162 also reports a NoSuchElementException, however I am uncertain if the issue I'm seeing is the same one because:

  1. #1162 seems to use an Accompanist supported animation. The crash I'm seeing does not, or at least not explicitly in the code I used.
  2. Some comments on #1162 report that downgrading to 'navigation-compose:2.4.2' / 'accompanist 0.24.7-alpha' / 'compose 1.2.0-beta01' resolves the issue - I've tried doing that but the app crashed also with those versions.
@github-actions
Copy link

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.

@github-actions github-actions bot added the stale Stale issues which are marked for closure label Jun 25, 2022
@tkirshboim
Copy link
Author

This is still an issue.

@github-actions github-actions bot removed the stale Stale issues which are marked for closure label Jun 26, 2022
@jbw0033
Copy link
Collaborator

jbw0033 commented Jul 11, 2022

I took a look at this and the code is attempting to add its own state to the BottomSheetNavigator, which isn't allowed.

You should use the provided rememberBottomSheetNavigator() API so your could should always look like:

val bottomSheetNavigator = rememberBottomSheetNavigator()
val navController = rememberNavController(bottomSheetNavigator)

ModalBottomSheetLayout(bottomSheetNavigator) {
    NavHost(navController = navController, startDestination = "xyz") {
        composable("xyz") {}
    }
}

@jbw0033 jbw0033 closed this as completed Jul 11, 2022
@tkirshboim
Copy link
Author

Thanks for the reply @jbw0033 .

I took a look at this and the code is attempting to add its own state to the BottomSheetNavigator, which isn't allowed.

  1. Would it make sense / be possible to have a clearer error message that hints to the actual cause of the error (i.e state being added to BottomSheetNavigator)? Right now this scenario throws a java.util.NoSuchElementException, which doesn't help debugging the problem.

  2. The use case for adding state to the BottomSheetNavigator here is to allow changing the result of confirmStateChange: (ModalBottomSheetValue) -> Boolean (defined in rememberModalBottomSheetState()), based on the app state. For example, an app might want to have some bottom sheets "sticky", i.e not dismissible, while allowing others to be dismissed. Does the Accompanist library support such a use case? If so, how can this be implemented?

@kunall17
Copy link

kunall17 commented Sep 1, 2022

@tkirshboim
Were you able to solve this problem?

@tkirshboim
Copy link
Author

@tkirshboim
Were you able to solve this problem?

@kunall17 Yes.

@kunall17
Copy link

kunall17 commented Sep 6, 2022

@tkirshboim
Were you able to solve this problem?

@kunall17 Yes.

@tkirshboim How did you solve this problem?

@tkirshboim
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants