Problem
Sentry.init registers all integrations synchronously on the calling thread (sentry/src/main/java/io/sentry/Sentry.java:374-385) — the main thread under auto-init. With ~17 default Android integrations this is the biggest remaining block of main-thread init work once the per-integration items (NDK etc.) are fixed.
Proposal
Keep a minimal synchronous core — options, scopes, SentryClient binding, UncaughtExceptionHandlerIntegration — and submit the rest of the registration loop to options.getExecutorService(), with an opt-in marker for integrations that genuinely need the main thread (AppLifecycleIntegration already self-posts when off-main).
Sentry.captureX immediately after init() keeps working: the client is bound synchronously and events queue on the transport.
Constraints
- The deliberate startup-crash blocking flush (
sentry-android-core/.../SendCachedEnvelopeIntegration.java:151-161) must still block init() — needs an explicit carve-out.
- Integration ordering guarantees (NDK before outbox watcher, AppLifecycle before ANR, ANR before Replay — see comments in
AndroidOptionsInitializer.installDefaultIntegrations) must be preserved. The single-threaded executor keeps submission order, but mixed sync/async registration could break it; audit each.
- Session auto-start +
isForegroundImportance() at the end of SentryAndroid.init (SentryAndroid.java:184-203) depend on integration state (LifecycleWatcher) — decide whether they move too.
Concrete follow-up to #5475 ("Move more init code async").
Problem
Sentry.initregisters all integrations synchronously on the calling thread (sentry/src/main/java/io/sentry/Sentry.java:374-385) — the main thread under auto-init. With ~17 default Android integrations this is the biggest remaining block of main-thread init work once the per-integration items (NDK etc.) are fixed.Proposal
Keep a minimal synchronous core — options, scopes,
SentryClientbinding,UncaughtExceptionHandlerIntegration— and submit the rest of the registration loop tooptions.getExecutorService(), with an opt-in marker for integrations that genuinely need the main thread (AppLifecycleIntegrationalready self-posts when off-main).Sentry.captureXimmediately afterinit()keeps working: the client is bound synchronously and events queue on the transport.Constraints
sentry-android-core/.../SendCachedEnvelopeIntegration.java:151-161) must still blockinit()— needs an explicit carve-out.AndroidOptionsInitializer.installDefaultIntegrations) must be preserved. The single-threaded executor keeps submission order, but mixed sync/async registration could break it; audit each.isForegroundImportance()at the end ofSentryAndroid.init(SentryAndroid.java:184-203) depend on integration state (LifecycleWatcher) — decide whether they move too.Concrete follow-up to #5475 ("Move more init code async").