Skip to content

App crashes or flashes white screen when navigating back from Presenter / Draft Presenter #48

Description

@SiroDevs

Pressing the back button from PresenterScreen or DraftPresenterScreen (and potentially other screens that use navController.popBackStack()) causes one of two symptoms: the app crashes outright, or the screen briefly flashes white before the previous destination appears. The issue is consistent and reproducible from any song or draft.

Steps to reproduce

  1. Open the app and navigate to the Search tab on the Home screen.
  2. Tap any song to open the Song Presenter.
  3. Press the system back button or the back arrow in the top bar.
  4. Observe: the app either crashes, or a white flash appears before the Home screen is shown.

The same behaviour occurs when pressing back from the Draft Presenter.

Expected behaviour

Pressing back should pop the current screen off the stack and return the user to the previous screen smoothly, with no crash or visual artefact.

Root cause (technical)

In AppNavHost.kt, the PresenterScreen and DraftPresenterScreen composables both read their required arguments (song/book and draft respectively) from navController.previousBackStackEntry?.savedStateHandle. This is incorrect. Once the presenter is on top of the stack, the previous entry is the Home screen — but when popBackStack() is called, the back stack changes mid-composition, making previousBackStackEntry transiently null. This causes a null argument to arrive at the composable during that recomposition frame, triggering an empty or error state before the screen has finished animating out — or crashing if a non-null value was assumed.

The correct pattern is to read arguments from the current entry's savedStateHandle, set by the caller before navigating:

// Caller (SongsList.kt) — already correct:
navController.currentBackStackEntry?.savedStateHandle?.set("book", book)
navController.currentBackStackEntry?.savedStateHandle?.set("song", song)
navController.navigate(Routes.PRESENT)

// AppNavHost — WRONG (reads from previous entry after navigation):
val song = navController.previousBackStackEntry
    ?.savedStateHandle?.get<SongEntity>("song")

// AppNavHost — CORRECT (reads from current entry, set before navigate()):
val song = navController.currentBackStackEntry
    ?.savedStateHandle?.get<SongEntity>("song")

The same fix applies to Routes.DRAFT_PRESENT, Routes.DRAFT_EDITOR, Routes.EDITOR, and Routes.LISTING, which all use previousBackStackEntry to retrieve their arguments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions