Skip to content

Jetpack Compose State Restoration: Preserve the Edit, Not the Whole Document

Separate saved document data from the small UI state needed to restore a Compose editor after configuration changes or process recreation.

GuideDeveloper tools

By

Updated 2 min read
Compose State Restoration: document illustration with IndieTools branding

A Compose editor should restore the user's place without treating the entire document as saved-instance state. Keep durable records in an appropriate data store and preserve only the small state needed to reconstruct the screen and its unfinished interaction.

Android's Compose state-saving guide distinguishes configuration changes, process recreation and persistent storage. It also cautions against placing large objects in the limited saved-state bundle.

Classify the state before choosing an API

Separate the saved record, unsaved edits, selected record identifier, scroll position and temporary presentation choices. Each has a different lifetime.

A receipt image may be durable data. The identifier of the receipt being edited is a small navigation value. An expanded details panel is transient interface state.

Writing these categories down prevents one convenient state holder from becoming the accidental storage system for everything.

Reconstruct from stable identifiers

Scan Pro Receipt describes receipt capture, editing and export, and declares Compose in the technology catalogue. Its implementation is not disclosed. The workflow is useful because losing a correction during an interruption can be more costly than losing an animation state.

Restore a stable record reference, then load the corresponding durable data. Define what happens if the record no longer exists or access to its file has changed.

Avoid retaining a large image or document collection in saved-instance state merely to recreate the screen quickly.

Give unsaved edits an explicit policy

Decide whether edits are stored incrementally, retained as a separate draft or intentionally discarded after a particular user action. Communicate that policy through save indicators and navigation behavior.

Do not call a value saved when it exists only in a composable's current memory. Likewise, restoring an old field value should not overwrite a newer durable record without a conflict decision.

Use a synthetic receipt with a deliberately corrected vendor name to distinguish restored edits from the original imported data.

Test different interruptions separately

Rotate or otherwise change configuration during editing. Then test system-driven process recreation through an appropriate controlled test setup.

A ViewModel can retain state across configuration changes, but Android documents that it does not itself survive process death. One successful rotation test therefore does not demonstrate the whole lifecycle.

Also test an explicit user exit according to the product's policy. Not every transient state needs to survive every form of dismissal.

Verify meaning after restoration

Check the selected record, unsaved fields, validation state and enabled actions. A screen that looks populated may still be bound to the wrong record or an obsolete save operation.

The companion Compose semantics guide covers how those controls communicate their meaning to assistive technology.

Keep restoration fixtures small and recognizable, without real expense documents. Record which lifecycle event was exercised and which values should survive.

Review these tests when moving state between a composable, a ViewModel and the data layer. The correct API depends on the state owner's responsibility, not only on convenience.

A dependable editor makes interruption predictable: it can explain what was saved, what was restored and what still requires the user's attention.

More guide articles