Skip to content

Android: eliminate task list flicker on cold start#306

Merged
dkhalife merged 3 commits intomainfrom
reduce_calls
Apr 23, 2026
Merged

Android: eliminate task list flicker on cold start#306
dkhalife merged 3 commits intomainfrom
reduce_calls

Conversation

@dkhalife
Copy link
Copy Markdown
Owner

@dkhalife dkhalife commented Apr 23, 2026

Problem

When opening the Android app, the cached task list flashes multiple times before stabilizing: labels disappear and reappear, and the whole cycle repeats two or three times.

Root causes

  1. Intra-refresh flickerSyncCoordinator.refreshAll() upserts tasks and replaces their label cross-refs one row at a time. TaskDao.replaceLabels does DELETE FROM task_labels then re-inserts; each write invalidates the @Transaction @Query backing observeTasks(), so the Flow emits intermediate states where tasks temporarily have no labels.

  2. Three refresh cycles per cold open — all of these triggered a full refreshAll():

    • TaskWizardApplication.onCreatesyncCoordinator.syncOnce()
    • TaskListViewModel.initrefreshTasks()
    • TaskListViewModel.initlabelRepository.refreshLabels() (which also just delegates to syncOnceBlocking)

    They serialize behind the coordinator mutex and each one produces its own flicker cycle.

Fix

  • Wrap SyncCoordinator.refreshAll() in db.withTransaction { ... } so Room batches table invalidations and emits a single Flow update per sync.
  • Drop the redundant labelRepository.refreshLabels() call from TaskListViewModel.initrefreshTasks() already refreshes labels via the coordinator.
  • Drop the eager syncCoordinator.syncOnce() from TaskWizardApplication.onCreate; the first screen's ViewModel triggers a refresh, and the NetworkMonitor availability listener still kicks one when connectivity flips on.

Net result on cold open: a single refresh cycle with a single UI update — no flash.

Copilot AI review requested due to automatic review settings April 23, 2026 22:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets Android cold-start task list flicker by reducing redundant sync triggers and attempting to batch Room invalidations so task/label observers emit fewer intermediate states during refresh.

Changes:

  • Removed an extra label refresh trigger from TaskListViewModel initialization to avoid redundant full refresh cycles.
  • Removed the eager syncCoordinator.syncOnce() call from TaskWizardApplication.onCreate, relying on other refresh triggers instead.
  • Wrapped SyncCoordinator.refreshAll() in a Room transaction via db.withTransaction { ... }.
Show a summary per file
File Description
android/app/src/main/java/com/dkhalife/tasks/viewmodel/TaskListViewModel.kt Removes redundant label refresh during VM init to reduce repeated refresh/flicker cycles.
android/app/src/main/java/com/dkhalife/tasks/TaskWizardApplication.kt Removes eager startup sync; keeps sync-on-connectivity callback; minor MSAL type import cleanup.
android/app/src/main/java/com/dkhalife/tasks/data/sync/SyncCoordinator.kt Adds DB-level transaction wrapper around refresh to reduce intermediate Room observer emissions.

Copilot's findings

  • Files reviewed: 3/3 changed files
  • Comments generated: 2

@dkhalife dkhalife merged commit 7815163 into main Apr 23, 2026
6 checks passed
@dkhalife dkhalife deleted the reduce_calls branch April 23, 2026 22:58
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.

2 participants