Skip to content

Comments

fix-Android: foregroundTaskOptions UninitializedPropertyAccessException in onDestroy#375

Open
alexsvtmdev wants to merge 1 commit intoDev-hwang:masterfrom
alexsvtmdev:fix/foregroundTaskOptions-uninitialized-in-onDestroy
Open

fix-Android: foregroundTaskOptions UninitializedPropertyAccessException in onDestroy#375
alexsvtmdev wants to merge 1 commit intoDev-hwang:masterfrom
alexsvtmdev:fix/foregroundTaskOptions-uninitialized-in-onDestroy

Conversation

@alexsvtmdev
Copy link

Summary

ForegroundService.onDestroy() crashes with UninitializedPropertyAccessException when Android destroys the service before onStartCommand() is called.

Root cause: The lateinit var foregroundTaskOptions is only initialized in loadDataFromPreferences() (called from onStartCommand()). If the system destroys the service before that call, onDestroy() accesses the uninitialized property and crashes.

Fix: Added ::foregroundTaskOptions.isInitialized guard — the exact same pattern already used for foregroundServiceStatus (fixed in commit 67da414).

When does this happen?

  • Android kills the app process under memory pressure, then tries to stop the service
  • Aggressive battery optimization (Samsung, Xiaomi, Huawei OEM implementations)
  • Quick swipe from recent apps on some devices before onStartCommand() runs

Crashlytics stack trace (production)

Fatal Exception: java.lang.RuntimeException:
  Unable to stop service ...ForegroundService@4e2f694:
  lateinit property foregroundTaskOptions has not been initialized
    at ForegroundService.onDestroy(ForegroundService.kt:207)

Changes

File: android/.../service/ForegroundService.ktonDestroy() method

// Before (crashes if onStartCommand was never called):
val allowAutoRestart = foregroundTaskOptions.allowAutoRestart

// After (safe — defaults to false if not initialized):
var allowAutoRestart = false
if (::foregroundTaskOptions.isInitialized) {
    allowAutoRestart = foregroundTaskOptions.allowAutoRestart
}

This follows the same pattern as the existing foregroundServiceStatus guard in the same method (commit 67da414).

Risk assessment

  • Minimal change: 1 file, +7/-1 lines
  • Safe default: If foregroundTaskOptions is not initialized, allowAutoRestart defaults to false (no auto-restart), which is the correct behavior when the service was never properly started
  • No behavioral change when the service lifecycle is normal (property is always initialized before onDestroy)

…on in onDestroy

When Android destroys ForegroundService before onStartCommand() is called
(e.g. process killed under memory pressure, aggressive battery optimization,
or quick swipe from recents on some OEMs), the lateinit property
`foregroundTaskOptions` is never initialized via `loadDataFromPreferences()`.

Accessing `foregroundTaskOptions.allowAutoRestart` in `onDestroy()` then
throws UninitializedPropertyAccessException, crashing the app.

This is the same pattern that was already fixed for `foregroundServiceStatus`
in commit 67da414. This commit applies the identical `::isInitialized` guard
to `foregroundTaskOptions`.

Crashlytics stack trace:
  Fatal Exception: java.lang.RuntimeException:
    Unable to stop service ...ForegroundService:
    lateinit property foregroundTaskOptions has not been initialized
  at ForegroundService.onDestroy(ForegroundService.kt:207)

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

1 participant