Skip to content

Fix NetworkOnMainThreadException when starting a download - #1893

Merged
tapframe merged 1 commit into
NuvioMedia:cmp-rewritefrom
Axl-Lvy:fix/download-network-on-main-thread
Sep 7, 2026
Merged

Fix NetworkOnMainThreadException when starting a download#1893
tapframe merged 1 commit into
NuvioMedia:cmp-rewritefrom
Axl-Lvy:fix/download-network-on-main-thread

Conversation

@Axl-Lvy

@Axl-Lvy Axl-Lvy commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a crash on starting a download. DownloadsTransferJobService closes the per network OkHttpClient connection pool synchronously on Dispatchers.Main.immediate, which closes pooled SSL sockets on the main thread and throws NetworkOnMainThreadException.

PR type

  • Reproducible bug fix
  • UI glitch/bug fix
  • Behavior bug/regression fix
  • Small maintenance only, with no UI or behavior change
  • Docs accuracy fix
  • Translation/localization only
  • Approved larger or directional change

Why

Starting a download crashes the app with NetworkOnMainThreadException whenever the transfer restarts on a network change (a common case: Wi-Fi state changing while a download is running). This is a hard crash, the process is killed after repeated occurrences.

Issue or approval

Fixes #1892

UI / behavior impact

  • No UI change
  • No behavior change
  • Behavior changed only to fix a documented bug/regression
  • UI change has explicit maintainer approval
  • Behavior change has explicit maintainer approval

Policy check

  • I have read and understood CONTRIBUTING.md.
  • This PR is small, focused, and limited to one problem.
  • This PR is not cosmetic-only.
  • Any UI change fixes a linked glitch/bug and includes visual proof, or this PR has no UI change.
  • Any behavior change fixes a linked bug/regression or has explicit approval, or this PR has no behavior change.
  • This PR does not bundle unrelated refactors, cleanups, formatting, or drive-by changes.
  • This PR does not add dependencies, architecture changes, migrations, or product-direction changes without explicit approval.
  • I listed the testing performed below.

Scope boundaries

Only the socket eviction call is moved off the main thread. Nothing else in execute() or the download flow is touched.

Testing

  • ./gradlew :composeApp:compileAndroidMain succeeds.
  • ./gradlew :composeApp:testAndroidHostTest --tests "com.nuvio.app.features.downloads.*" passes for the tests that exercise AndroidDownloadScheduler.execute() (scheduledDownloadsArePersistedUserInitiatedTransfers, pausedTransferIsNotRestartedBySystemRedelivery, completedRenameIsRecoveredAfterProcessDeathBeforeStateCommit, backgroundExecutionDoesNotNeedRepositoryOrActivityCallbacks). One unrelated pre existing test in that class fails locally due to a Robolectric native runtime path issue in my environment, unrelated to this change.
  • Reproduced the original crash on device (physical phone, app 0.4.14) with adb logcat, confirmed the fix removes the main thread socket close from the onNetworkChanged restart path by code inspection.

Screenshots / Video (UI changes only)

Not a UI change.

Breaking changes

None.

Linked issues

Fixes #1892

DownloadsTransferJobService runs its coroutine scope on Dispatchers.Main.immediate. AndroidDownloadScheduler.execute() closed the per network OkHttpClient's connection pool synchronously in its finally block. That call closes pooled SSL sockets and crashes with NetworkOnMainThreadException whenever onNetworkChanged restarts the transfer.

The eviction now runs on Dispatchers.IO.
@tapframe
tapframe merged commit ffab1e6 into NuvioMedia:cmp-rewrite Sep 7, 2026
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.

[Bug]: Download crashes immediately with NetworkOnMainThreadException

2 participants