perf(android): Init shake detector off the main thread#5784
Merged
Conversation
FeedbackShakeIntegration.register() resolved the accelerometer via SensorManager synchronously on the calling thread, which under auto-init is the main thread. On a Pixel 10 this first SensorManager access measured ~1.75ms, making it the single most expensive integration in the Sentry.init register loop. Submit the pre-warm init() to the executor service instead. start() already re-runs the idempotent init() on demand, so shake detection still works if an activity resumes before the warm-up completes. SentryShakeDetector's lifecycle methods are now synchronized so the executor warm-up and a main-thread start() cannot race on the sensor fields. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
runningcode
requested review from
0xadam-brown,
adinauer,
markushi and
romtsn
as code owners
July 17, 2026 15:14
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📲 Install BuildsAndroid
|
runningcode
marked this pull request as draft
July 17, 2026 15:20
Contributor
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 5b1a06b | 352.27 ms | 413.70 ms | 61.43 ms |
| 2124a46 | 319.19 ms | 415.04 ms | 95.85 ms |
| ad8da22 | 314.52 ms | 352.47 ms | 37.95 ms |
| d15471f | 304.55 ms | 408.43 ms | 103.87 ms |
| 0ee65e9 | 317.37 ms | 366.50 ms | 49.13 ms |
| 2195398 | 351.77 ms | 433.22 ms | 81.45 ms |
| ee747ae | 358.21 ms | 389.41 ms | 31.20 ms |
| abfcc92 | 309.54 ms | 380.32 ms | 70.78 ms |
| 8558cac | 306.16 ms | 355.24 ms | 49.09 ms |
| d15471f | 310.26 ms | 377.04 ms | 66.78 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 5b1a06b | 0 B | 0 B | 0 B |
| 2124a46 | 1.58 MiB | 2.12 MiB | 551.51 KiB |
| ad8da22 | 1.58 MiB | 2.29 MiB | 719.83 KiB |
| d15471f | 1.58 MiB | 2.13 MiB | 559.54 KiB |
| 0ee65e9 | 0 B | 0 B | 0 B |
| 2195398 | 0 B | 0 B | 0 B |
| ee747ae | 1.58 MiB | 2.10 MiB | 530.95 KiB |
| abfcc92 | 1.58 MiB | 2.13 MiB | 557.31 KiB |
| 8558cac | 0 B | 0 B | 0 B |
| d15471f | 1.58 MiB | 2.13 MiB | 559.54 KiB |
runningcode
marked this pull request as ready for review
July 20, 2026 07:09
romtsn
approved these changes
Jul 20, 2026
romtsn
left a comment
Member
There was a problem hiding this comment.
I think the bot comment needs addressing but LGTM otherwise, pre-approving
…618) A warm-up init submitted to the executor could be drained after the integration's close() ran, since integrations shut down before the executor. That re-resolved the sensor and leaked a HandlerThread. Guard init()/start() with a closed latch so a late warm-up is a no-op. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6b4dae5. Configure here.
The closed latch added to neutralize a warm-up drained after close() was permanent, so re-registering the same integration (e.g. a second Sentry.init reusing the same options) left shake detection off with no recovery. register() now re-arms the detector via reopen(), which the stale-warm-up path (init()) deliberately does not, preserving the drain-after-close guard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
romtsn
reviewed
Jul 21, 2026
runningcode
enabled auto-merge (squash)
July 21, 2026 12:29
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.

Summary
FeedbackShakeIntegration.register()resolved the accelerometer viaSensorManagersynchronously on the calling thread — the main thread under auto-init. On a Pixel 10 (Android 17, release build) this firstSensorManageraccess measured ~1.75 ms, making it the single most expensive integration in theSentry.initregister loop (the loop total was ~5.1 ms).This moves the pre-warm
shakeDetector.init(...)ontooptions.getExecutorService().SentryShakeDetector.start()already re-runs the idempotentinit()on demand, so shake detection still works if an activity resumes before the warm-up finishes.SentryShakeDetector's lifecycle methods (init/start/stop/close) are nowsynchronizedso the executor warm-up and a main-threadstart()cannot race on the sensor fields.Measurement (Pixel 10, release, median of 10 cold starts)
FeedbackShakeIntegration.register()Follow-up to JAVA-618. Companion PR defers the other big synchronous item (NDK init).