downloadPriority property
Scheduling priority for model downloads — and it must differ per platform.
background_downloader documents 0 <= priority <= 10 with 0 being the HIGHEST, default 5. This was 10 everywhere, which on iOS is actively
harmful and on Android is inert.
iOS maps it straight onto URLSession: BDPlugin.swift does
urlSessionDownloadTask.priority = 1 - Float(task.priority) / 10. So 10
produced 0.0 — below URLSessionTask.lowPriority (0.25) — for a
multi-gigabyte download the user is watching. 0 gives 1.0.
Android uses priority for exactly two things: the holding queue, which
this package never enables, and expedited = priority < 5 in
BDPlugin.kt. Expedited is the wrong trade for a 2-4 GB transfer, for two
independent reasons:
- it SHORTENS the OS execution guarantee from 10 minutes to 3.
JobSchedulerServicedefinesRUNTIME_MIN_GUARANTEE_MS= 10 min andRUNTIME_MIN_EJ_GUARANTEE_MS= 3 min, and caps expedited at the regular figure; developer.android.com says expedited work is for "short" tasks. Expedited work also draws on a separate 24-hour budget. - it currently hangs the download outright. WorkManager caps a task at 9
minutes; background_downloader survives that by pausing and
RE-ENQUEUING with
initialDelayMillis = 1000. The re-enqueue setssetInitialDelayand, below priority 5,setExpeditedon the same builder, andWorkRequest.Builder.build()throwsIllegalArgumentException: Expedited jobs cannot be delayed. The throw is swallowed to aLog.w,doEnqueue'sfalseis discarded, and the runner returnsTaskStatus.pausedanyway.
Note the crash is only reachable for RESUMABLE downloads. HuggingFace
serves weak ETags, so allowPause is false for those URLs and the native
side fails outright at 9 minutes rather than pausing and re-enqueuing —
which is every URL in the example app. Anyone trying to reproduce the hang
against a HuggingFace model will not see it and may conclude this was
unnecessary. Self-hosted, GCS, Firebase Storage and Kaggle URLs do resume,
and those are the ones that hang.
So the correct Android value is the highest that is NOT expedited: 5, the package default. Against the old 10 this changes nothing observable on Android — priority there is inert outside the holding queue — which is the point: 10 cost nothing, and anything below 5 would.
On the package author's suggestion of 0: it was offered on the grounds
that it triggers Android's User Initiated Data Transfer, which has no
9-minute limit. That is not what the shipped code does — his own open
PR #710 says setUserInitiated(true) was never called on the JobInfo —
and the expedited crash is his open PR #709. Revisit both when they land.
Keyed off Platform.isAndroid, NOT defaultTargetPlatform: the latter is
a UI-intent signal that a host can legitimately override with
debugDefaultTargetPlatformOverride to preview Cupertino, and doing that
in a debug build on a real Android phone would hand this an iOS answer.
Implementation
static int get downloadPriority =>
priorityForPlatform(isAndroid: Platform.isAndroid);