Package 

Object OneSignalDispatchers


  • 
    public class OneSignalDispatchers
    
                        

    Optimized threading manager for the OneSignal SDK.

    Performance optimizations:

    • Lazy initialization to reduce startup overhead

    • Custom thread pools for both IO and Default operations

    • Optimized thread pool configuration (smaller pools)

    • Small bounded queues (10 tasks) to prevent memory bloat

    • Reduced context switching overhead

    • Efficient thread management with controlled resource usage

    Made public to allow mocking in tests via IOMockHelper.

    • Method Detail

      • prewarm

         final Unit prewarm()

        Triggers the lazy initialization of IO, Default, and SerialIO (and their backing executors, dispatchers, and scopes) on a short-lived background thread.

        Background: The lazy by lazy properties below construct ThreadPoolExecutor instances and wrap them in asCoroutineDispatcher() + SupervisorJob() + CoroutineScope(...). Production OTel shows that when the first caller of launchOnIO / launchOnSerialIO is on the main thread (Activity-lifecycle handler, JobService.onStartJob, etc.), the construction cost — which includes a kotlinx.coroutines.BuildersKt.launch that hits ThreadPoolExecutor.execute and LinkedBlockingQueue.offer synchronously — is paid on the calling thread, blocking the main thread for many seconds on cold start. See SDK-4507.

        Calling prewarm from a non-time-sensitive spot in com.onesignal.OneSignal.initWithContext shifts that cost to a dedicated OneSignal-prewarm daemon thread, so the first production caller — including main-thread lifecycle handlers — only pays the much cheaper "submit work to an already-constructed executor" cost.

        Idempotent and fire-and-forget: a no-op on second and subsequent calls. Safe to invoke from any thread; the heavy lifting always happens on the daemon thread we spawn here, not on the caller. Failures are logged and swallowed because the executors retain their existing fallback paths (e.g. Dispatchers.IO.limitedParallelism(1) for SerialIO) and a failed prewarm will simply mean the first production caller pays the original cost.

      • getIO

         final CoroutineDispatcher getIO()
      • getDefault

         final CoroutineDispatcher getDefault()