Skip to content

fix(android): identify the screen appear event by name instead of class - #6692

Merged
alwx merged 3 commits into
getsentry:mainfrom
TaduJR:fix/android-ttid-event-name-matching
Sep 10, 2026
Merged

fix(android): identify the screen appear event by name instead of class#6692
alwx merged 3 commits into
getsentry:mainfrom
TaduJR:fix/android-ttid-event-name-matching

Conversation

@TaduJR

@TaduJR TaduJR commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

RNSentryReactFragmentLifecycleTracer waited for the react-native-screens appear event by comparing its canonical class name:

if ("com.swmansion.rnscreens.events.ScreenAppearEvent"
    .equals(event.getClass().getCanonicalName())) {

Class names are not stable once R8 optimization is on. React Native Event subclasses share a superclass and a constructor signature, which makes them candidates for merging, and R8 collapses a group of them into one class that answers to a single name. It also rewrites the compared string literal to that name, so the comparison then matches every event in the group rather than one.

The event is now identified by Event.getEventName(), which React Native documents as "the name of this event as registered in JS". react-native-screens registers topAppear as the onAppear prop, so the name is part of its public contract and cannot change without breaking it. Unoptimized builds behave exactly as before.

The sibling check against com.swmansion.rnscreens.ScreenStackFragment is left as is. androidx.fragment ships a consumer rule that keeps public Fragment subclasses with a public no-arg constructor, and Android requires that constructor for fragment recreation, so that class is never merged.

💡 Motivation and Context

Fixes #6691
With R8 optimization enabled, ui.load.initial_display closes on whichever merged event dispatches first rather than on the screen appear event. topWillAppear always precedes topAppear, and events such as topFocus and topAttached can precede both, so time to initial display is reported shorter than it was. Nothing throws, and every diagnostic on this path logs at SentryLevel.DEBUG, so the data is wrong silently.

This affects any app that enables optimization, which AGP 9 makes the default by dropping support for the ProGuard file that carried -dontoptimize.

Reproduction: REPRO_URL. Four dependencies, no patched libraries, the R8 that AGP ships. There ScreenAppearEvent is merged into React Native's own DrawerClosedEvent, and the merged class holds 22 event names behind one class name.

💚 How did you test it?

Added unit tests to RNSentryReactFragmentLifecycleTracerTest, which previously covered listener registration but not which event triggers the first draw. One asserts that topAppear registers the first draw listener and removes the event listener, one asserts that topWillAppear does neither.

The reported behaviour was confirmed by disassembling the release dex of the reproduction, where the compared literal had been rewritten to the merged class name.

📝 Checklist

  • I added tests to verify 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.
  • All tests passing.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.
  • No breaking changes.

🔮 Next steps

An alternative that needs no code change is to ship -keep class com.swmansion.rnscreens.events.ScreenAppearEvent as a consumer ProGuard rule in the SDK. That keeps the class name intact but leaves the identity check dependent on the optimizer, which is why matching by event name is proposed instead.

@TaduJR
TaduJR marked this pull request as draft September 9, 2026 18:07
@TaduJR
TaduJR force-pushed the fix/android-ttid-event-name-matching branch from 3132d3b to f2bffa1 Compare September 9, 2026 18:13
@TaduJR
TaduJR force-pushed the fix/android-ttid-event-name-matching branch from f2bffa1 to 77a2d2d Compare September 9, 2026 18:21
@TaduJR
TaduJR marked this pull request as ready for review September 9, 2026 18:37
@antonis antonis added the ready-to-merge Triggers the full CI test suite label Sep 10, 2026
@alwx

alwx commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Hey @TaduJR,

Thanks for submitting this PR! I've added a small comment to the code, and I think that except this really small thing, everything looks good for me.

@TaduJR

TaduJR commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Hi @alwx

Thanks so much for reviewing.

Addressed your concern.

TIA.

@TaduJR
TaduJR requested a review from alwx September 10, 2026 09:17
@alwx
alwx merged commit 5bef5f4 into getsentry:main Sep 10, 2026
62 of 63 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android: time to initial display is understated in R8-optimized builds because the screen appear event is matched by class name

3 participants