Android: eliminate task list flicker on cold start#306
Merged
Conversation
Contributor
There was a problem hiding this comment.
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
TaskListViewModelinitialization to avoid redundant full refresh cycles. - Removed the eager
syncCoordinator.syncOnce()call fromTaskWizardApplication.onCreate, relying on other refresh triggers instead. - Wrapped
SyncCoordinator.refreshAll()in a Room transaction viadb.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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
Intra-refresh flicker —
SyncCoordinator.refreshAll()upserts tasks and replaces their label cross-refs one row at a time.TaskDao.replaceLabelsdoesDELETE FROM task_labelsthen re-inserts; each write invalidates the@Transaction @QuerybackingobserveTasks(), so the Flow emits intermediate states where tasks temporarily have no labels.Three refresh cycles per cold open — all of these triggered a full
refreshAll():TaskWizardApplication.onCreate→syncCoordinator.syncOnce()TaskListViewModel.init→refreshTasks()TaskListViewModel.init→labelRepository.refreshLabels()(which also just delegates tosyncOnceBlocking)They serialize behind the coordinator mutex and each one produces its own flicker cycle.
Fix
SyncCoordinator.refreshAll()indb.withTransaction { ... }so Room batches table invalidations and emits a single Flow update per sync.labelRepository.refreshLabels()call fromTaskListViewModel.init—refreshTasks()already refreshes labels via the coordinator.syncCoordinator.syncOnce()fromTaskWizardApplication.onCreate; the first screen's ViewModel triggers a refresh, and theNetworkMonitoravailability listener still kicks one when connectivity flips on.Net result on cold open: a single refresh cycle with a single UI update — no flash.