getsentry / getsentry/sentry-java
Nav3: Multistack support
- Lenguaje dominante
- Kotlin
- Estrellas
- 1.4k
- Forks
- 478
- Merge medio
- 2 d 23 h
- PR fusionados (30 d)
- 67
Descripción
### Problem Statement
Apps with bottom tabs, drawer navigation, or similar patterns often maintain multiple independent backstacks – one per top-level destination – so that users can switch tabs without losing their place. [Nav3]() doesn't provide a built-in multi-back-stack API; instead, apps own multiple `NavBackStack` instances and merge their entries before passing them to `NavDisplay` (see the [`multiplestacks` recipe]()).
The Stage 1 integration (getsentry/sentry-java#5000) and multipane support (getsentry/sentry-java#5649) handle a single `SnapshotStateList` backstack. When an app uses multiple stacks, the SDK needs to understand which stack is active and scope its telemetry accordingly.
### Solution Brainstorm
* **Stack identification.** Introduce a `stack_id` concept so breadcrumbs, transactions, and crash context can group navigations per stack. This could be a user-supplied label per stack (e.g. the tab route key's name), or inferred from the `NavBackStack` identity.
* **API surface.** Provide a way to register multiple backstacks with a shared `SentryNavStateHolder`, or create per-stack holders that coordinate. The app tells us which stack is currently active (likely by passing the active `topLevelRoute` or equivalent).
* `scope.screen` – set to the active stack's top route. When the user switches tabs, this triggers a navigation breadcrumb and updates `scope.screen` to the new stack's current top.
* **Breadcrumbs** – capture both intra-stack navigation (push/pop within a tab) and inter-stack switches (tab change). Include `stack_id` in breadcrumb data so the two can be distinguished. A tab switch breadcrumb might look like `{ from: "/settings/profile", to: "/home/feed", stack_id: "home" }`.
* **Transactions** – when the user switches to a stack whose top entry hasn't changed, should we start a new transaction? Probably not – the screen was already loaded. Only start a transaction on an actual new destination within the stack.
* **Crash context (**`contexts.navigation`**)** – include all stacks (not just the active one), capped by `maxBackstackSize` total across stacks. Mark which stack is active.
Open questions:
* Should `contexts.navigation.backstack` flatten all stacks into one list, or nest them by `stack_id`?
* How do multistack and multipane compose? A tablet app might have bottom tabs (multistack) where one tab shows a list-detail layout (multipane). The primary pane logic from Stage 2 should still apply within the active stack.
* Should tab switches reuse the existing `"navigation"` breadcrumb category or get a distinct one (e.g. `"stack_switch"`)?
* Do we want to revisit Nav2 simplifications alongside this (nested nav graphs, dialog/bottom-sheet transaction behavior)?
### Existing Nav2 support
Nav2 supports multiple backstacks natively via `NavController.navigate()` with `saveState = true` / `restoreState = true`, commonly used with `NavigationBar` or `BottomNavigation`. However, the current Nav2 integration does not distinguish between stacks – it sees a flat stream of destination changes on a single `NavController` and treats every destination change identically. There is no `stack_id`, no differentiation between intra-tab navigation and tab switches, and no per-stack grouping in crash context. A tab switch looks the same as a forward navigation in telemetry.
Guía de contribución
Línea de trabajo
Start by reviewing the Nav3 multiplestacks recipe and the Stage 1 and multipane integrations referenced in the issue. Determine how multiple NavBackStack instances, the active top-level route, and NavDisplay are represented before resolving the open API and telemetry questions. Done means the multistack behavior and its interaction with Nav2, multipane support, breadcrumbs, transactions, and navigation context are specified and covered by tests.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- android, kotlin
- Área
- mobile, observability
- Tipo de issue
- Nueva funcionalidad
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Tranquilo
- Claridad
- Necesita aclaración
- Aptitud para principiantes
- 30/100