Skip to content

feat(android): Nav3 support for multi-Activity and multi-Fragment applications - #6301

Open
0xadam-brown wants to merge 4 commits into
mainfrom
feat/sentry-nav-effect-lifecycle
Open

0xadam-brown wants to merge 4 commits into
mainfrom
feat/sentry-nav-effect-lifecycle

Conversation

@0xadam-brown

@0xadam-brown 0xadam-brown commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

PR Stack (Nav3 Lifecycle)


📜 Description

PR stack lets us support Nav3 for app architectures involving multiple NavDisplay <> SentryNavEffect pairs, subject to certain limitations (see the "Still not supported" list below). Prior to this stack, we assumed only one NavDisplay <> SentryNavEffect pair would be active at a time.

Supported

  1. A single-Activity app with one NavDisplay <> SentryNavEffect pair.
  2. A multi-Activity app where each Activity has its own NavDisplay <> SentryNavEffect pair.
  3. A multi-Fragment app where each Fragment has its own NavDisplay <> SentryNavEffect pair.
  4. A ViewPager2 whose pages are Fragments, each with its own NavDisplay <> SentryNavEffect pair.
  5. An Activity or Fragment with its own NavDisplay that stays visible beneath a DialogFragment or translucent Activity with its own NavDisplay.

Before this PR stack, we only supported (1) and its functional equivalents.

Still not supported

  1. Nested NavDisplay <> SentryNavEffect pairs in the same Activity or Fragment.
  2. Side-by-side NavDisplay <> SentryNavEffect pairs in the same Activity or Fragment.
  3. SentryNavEffect instances 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.
  4. SentryNavEffect instances in pages or tabs that share their host's lifecycle, such as Compose HorizontalPager pages, ViewPager2 pages that aren't Fragments, or tabs kept in the composition at once. (Those pages or tabs share one LifecycleOwner, so at most one can call SentryNavEffect.)

🔎 The basic approach

Supporting the new setups listed above requires coordinating multiple, simultaneously active SentryNavEffects and their updates to the current (mutable + shared) IScope vended by IScopes.

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.lifecycle package.

The basic idea was to replace the IScopes instance our BackStackObserver already 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 new NavLeaseCoordinator.)

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

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

#skip-changelog

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 723b40a

@sentry

sentry Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.61.1 (1) release

⚙️ sentry-android Build Distribution Settings

@0xadam-brown
0xadam-brown marked this pull request as ready for review October 20, 2026 15:30
@0xadam-brown 0xadam-brown added the sanity-check PR needs a lightweight review for obvious issues label Oct 20, 2026
@0xadam-brown 0xadam-brown changed the title feat(android): Support multiple Nav3 lifecycle owners feat(android): Lifecycle owner support for Nav3 Oct 20, 2026
@0xadam-brown 0xadam-brown changed the title feat(android): Lifecycle owner support for Nav3 feat(android): LifecycleOwner support for Nav3 Oct 20, 2026
@0xadam-brown 0xadam-brown changed the title feat(android): LifecycleOwner support for Nav3 feat(android): Multiple LifecycleOwner support for Nav3 Oct 21, 2026
@0xadam-brown 0xadam-brown removed the sanity-check PR needs a lightweight review for obvious issues label Oct 21, 2026
@0xadam-brown
0xadam-brown force-pushed the feat/sentry-nav-effect-lifecycle branch from c2667a5 to c464ea3 Compare October 21, 2026 11:27
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.
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 0xadam-brown changed the title feat(android): Multiple LifecycleOwner support for Nav3 feat(android): Nav3 support for multi-Activity and multi-Fragment applications Oct 22, 2026
fun unregisterCandidate(owner: Any, scope: IScope?) {
val candidate = findCandidate(owner) ?: return

try {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think configureScope already catches everything, so no exception gets to the host app, and I don't think we have this pattern of the SDK protectcting itself from throwing scope observers. Do we want to introduce this here? If not, we could drop a good chunk from unregisterCandidate and transferLeaseTo.

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.)
Comment thread gradle/libs.versions.toml
androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version = "1.3.5" }
androidx-lifecycle-common-java8 = { module = "androidx.lifecycle:lifecycle-common-java8", version.ref = "androidxLifecycle" }
androidx-lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "androidxLifecycle" }
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version = "2.8.3" }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: is this the min supported version that our integration can work with?

This branch has not been deployed

No deployments
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

Successfully merging this pull request may close these issues.

2 participants