Repository navigation
feat(android): Nav3 support for multi-Activity and multi-Fragment applications - #6301
Merged
Merged
Conversation
Contributor
|
📲 Install BuildsAndroid
|
This was referenced Oct 20, 2026
0xadam-brown
marked this pull request as ready for review
October 20, 2026 15:30
5 of 9 tasks
0xadam-brown
force-pushed
the
feat/sentry-nav-effect-lifecycle
branch
from
October 21, 2026 11:27
c2667a5 to
c464ea3
Compare
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Oct 21, 2026
Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
3 of 6 tasks
Part 1 of our Nav3 support for multi-Activity and multi-Fragment applications Introduces NavLeaseCoordinator, a lifecycle-aware lease manager that selects which SentryNavEffect instance may publish nav data to a shared IScope and create nav transactions under it.
0xadam-brown
requested review from
adinauer,
markushi,
romtsn and
runningcode
as code owners
October 22, 2026 07:49
romtsn
reviewed
Oct 22, 2026
Part 2 of our Nav3 support for multi-Activity and multi-Fragment applications Introduces NavScopes, which lets BackStackObserver talk to a facade that knows when to swizzle between the real, shared IScope used by all SentryNavEffects vs a per-instance staging area. Effects that later gain the right to update the shared IScope can publish their staged values.
…AVA-785) (#6305) Part 3 of our Nav3 support for multi-Activity and multi-Fragment applications Introduces CoordinatedBackStackObserver, which lets us inject the new NavScopes version of IScopes into BackStackObserver. (NavScopes is a facade that knows when to toggle between the real IScope instance shared by all SentryNavEffects vs a per-effect staging area.)
romtsn
reviewed
Oct 22, 2026
…fs (JAVA-785) (#6307) Part 4 of our Nav3 support for multi-Activity and multi-Fragment applications Adds integration tests verifying the behavior of overlapping SentryNavEffects.
…6309) Part 5 of our Nav3 support for multi-Activity and multi-Fragment applications Add multi-Activity and multi-Fragment Nav3 scenarios with shared transaction history so lifecycle handoffs can be exercised in the Android sample app.
Expose lifecycle-runtime-compose as a runtime dependency so consumers resolve at least the version required by Sentry Navigation3. Refs JAVA-785 Co-Authored-By: OpenAI Codex <noreply@openai.com>
Member
Author
|
Using |
0xadam-brown
enabled auto-merge (squash)
October 23, 2026 12:33
sentry-junior Bot
added a commit
that referenced
this pull request
Oct 23, 2026
Keep both current Unreleased changelog entries after #6301 merged.
sentry-junior Bot
added a commit
that referenced
this pull request
Oct 23, 2026
Keep both Unreleased changelog entries after #6301 merged.
This was referenced Oct 27, 2026
0xadam-brown
added a commit
to getsentry/sentry-docs
that referenced
this pull request
Nov 3, 2026
…85) (#20137) Update the Android Navigation page to reflect the changes in the PR stack rooted at [sentry-java #6301](getsentry/sentry-java#6301), which introduces support for Nav3 setups involving multiple NavDisplay <> SentryNavEffect pairs. Supported vs non-supported setups are now listed explicitly.
0xadam-brown
added a commit
that referenced
this pull request
Nov 4, 2026
Make the multi-Activity and multi-Fragment support introduced by the #6301 PR stack play nicely with ViewPager2. BACKGROUND The approach in #6301 was smart about staging nav data (ie, screen name + nav context), but it didn't do the same for nav transactions. A new nav transaction could be started only if the lease was owned at the time of navigation, where "navigation" == initialization or modification of the nav back stack. Because the lease had to be owned, that meant that the Activity or Fragment hosting the SentryNavEffect requesting the lease had to be in a resumed state. That^^ assumption made sense for most use cases, because usually initialization of an Activity or Fragment's nav back stack coincides with the Activity or Fragment being visible and therefore being able to preempt the lease from the previous leaseholder. But the assumption didn't pan out for ViewPager2, because ViewPager2 preloads neighboring pages. That means it initializes the nav back stack for Fragments that aren't in a resumed state and therefore can't preempt the lease, causing them to drop their initial nav transaction and any spans created by the initial destination screen. Sigh. THE SOLUTION The solution this commit implements is to create a mechanism similar to the data staging from #6301, but for transactions. Doing so lets us separate back stack initialization observed during preloading vs attempted lease acquisition when a ViewPager2 page becomes visible. In particular, the new StagedNavTransaction class tracks requests to start nav transactions when a SentryNavEffect is created even if it doesn't currently have the lease. If the lease is later acquired and the transaction slot is available on the shared IScope, the staged transaction is started, which keeps ViewPager2 happy.
0xadam-brown
added a commit
that referenced
this pull request
Nov 4, 2026
Make the multi-Activity and multi-Fragment support introduced by the #6301 PR stack play nicely with ViewPager2. BACKGROUND The approach in #6301 was smart about staging nav data (ie, screen name + nav context), but it didn't do the same for nav transactions. A new nav transaction could be started only if the lease was owned at the time of navigation, where "navigation" == initialization or modification of the nav back stack. Because the lease had to be owned, that meant that the Activity or Fragment hosting the SentryNavEffect requesting the lease had to be in a resumed state. That^^ assumption made sense for most use cases, because usually initialization of an Activity or Fragment's nav back stack coincides with the Activity or Fragment being visible and therefore being able to preempt the lease from the previous leaseholder. But the assumption didn't pan out for ViewPager2, because ViewPager2 preloads neighboring pages. That means it initializes the nav back stack for Fragments that aren't in a resumed state and therefore can't preempt the lease, causing them to drop their initial nav transaction and any spans created by the initial destination screen. Sigh. THE SOLUTION The solution this commit implements is to create a mechanism similar to the data staging from #6301, but for transactions. Doing so lets us separate back stack initialization observed during preloading vs attempted lease acquisition when a ViewPager2 page becomes visible. In particular, the new StagedNavTransaction class tracks requests to start nav transactions when a SentryNavEffect is created even if it doesn't currently have the lease. If the lease is later acquired and the transaction slot is available on the shared IScope, the staged transaction is started, which keeps ViewPager2 happy. REFACTORING INCLUDED Included in this commit is a refactor of code in the .navigation3.lifecycle package. The refactor lets us separate three responsibilities: - Lease coordination: NavLeaseCoordinator observes registered owners’ lifecycles and decides which SentryNavEffect may publish navigation state. - State publication: Each effect’s NavScopes publishes and withdraws its navigation data and transaction together when ownership changes. - Transaction management: Each effect gets a transaction handle that manages starting, finishing, binding, and restoring its transaction. The coordinator no longer retains transactions itself.
5 of 9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Stack (Nav3 Lifecycle)
📜 Description
PR stack lets us support Nav3 for app architectures involving multiple
NavDisplay<>SentryNavEffectpairs, subject to certain limitations (see the "Still not supported" list below). Prior to this stack, we assumed only oneNavDisplay<>SentryNavEffectpair would be active at a time.Supported
NavDisplay<>SentryNavEffectpair.NavDisplay<>SentryNavEffectpair.NavDisplay<>SentryNavEffectpair.ViewPager2whose pages are Fragments, each with its ownNavDisplay<>SentryNavEffectpair.NavDisplaythat stays visible beneath aDialogFragmentor translucent Activity with its ownNavDisplay.Before this PR stack, we only supported (1) and its functional equivalents.
Still not supported
NavDisplay<>SentryNavEffectpairs in the same Activity or Fragment.NavDisplay<>SentryNavEffectpairs in the same Activity or Fragment.SentryNavEffectinstances in multiple Activities or Fragments that users can interact with at the same time, such as two Activities from the same app in multi-resume mode.SentryNavEffectinstances in pages or tabs that share their host's lifecycle, such as ComposeHorizontalPagerpages,ViewPager2pages that aren't Fragments, or tabs kept in the composition at once. (Those pages or tabs share oneLifecycleOwner, so at most one can callSentryNavEffect.)🔎 The basic approach
Supporting the new setups listed above requires coordinating multiple, simultaneously active
SentryNavEffects and their updates to the current (mutable + shared)IScopevended byIScopes.Like all forms of state management around Android lifecycles + shared mutable state, that code isn't exactly simple. To keep things manageable (and easy to update!), I've been careful to sequester all coordination logic to the new
.navigation3.lifecyclepackage.The basic idea was to replace the
IScopesinstance ourBackStackObserveralready talked to with a smarter version (NavScopes) that could toggle between the shared underlying scope and a per-instance staged version, depending on whether the observer was associated with the incoming or outgoing SentryNavEffect. (Under the hood, NavScopes relies on lease-based ownership to decide who can update the scope, which is overseen by the newNavLeaseCoordinator.)That^^ let me keep updates to SentryNavEffect, BackStackObserver, etc. to a minimum, and it makes it easy to swap out our implementation in the future, should we ever hide our IScopes API behind a
LocalSentrySpan-esque system (or any of a number of other possibilities) 🎉 .💡 Motivation and Context
Lets us support the multi-Activity and multi-Fragment app setups listed above. Those setups are common, and without the changes here, spans and nav state would be incorrect when transitioning between Activities or Fragments.
That's worrisome, because Activity / Fragment startup logic is a common source of bugs and crashes, so properly attributing Sentry data there is especially worthwhile.
addresses: JAVA-785
💚 How did you test it?
Each stack branch is formatted, API-dumped, built, and tested independently before its PR is opened.
📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
main.#skip-changelog